Respuesta: Vamos A.h
incluyen b.h
, c.h
y d.h
sólo si se necesitaba hacer que la construcción tenga éxito La regla de oro es: solo incluir tanto código en un archivo de encabezado como sea necesario. Todo lo que no se necesite de inmediato en A.h
debe incluirse en A.cpp
.
Razonamiento: Mientras menos código se incluya en los archivos de encabezado, es menos probable que deba volver a compilar el código que usa el archivo de encabezado después de hacer algún cambio en alguna parte. Si hay muchas referencias #include
entre diferentes archivos de encabezado, cambiar cualquiera de ellas requerirá la reconstrucción de todos los demás archivos que incluyen el archivo de encabezado modificado - recursivel. Por lo tanto, si decide tocar algún archivo de encabezado de nivel, esto podría reconstruir grandes partes de su código.
Al usar forward declarations siempre que sea posible en los archivos de encabezado, se reduce el acoplamiento de los archivos de origen y, por lo tanto, la compilación es más rápida. Tales declaraciones directas pueden usarse en muchas más situaciones de las que se podría pensar. Como regla general, sólo es necesario el archivo de cabecera t.h
(que define un tipo T
) si
- declara una variable miembro de tipo
T
(nota, esto no incluye declarar un puntero-a T
).
- Escriba algunas funciones en línea que acceden a los miembros de un objeto del tipo
T
.
Haces no necesidad de incluir la declaración de T
si su archivo de cabecera simplemente
- Declara constructores/funciones que tienen referencias o punteros a un objeto
T
.
- Declara funciones que devuelven un objeto
T
por puntero, referencia o valor.
- Declara las variables miembro que son referencias o punteros a un objeto
T
.
Considere esta declaración de clase; cuál de los archivos de inclusión para A
, B
y C
lo que realmente necesita para incluir ?:
class MyClass
{
public:
MyClass(const A &a);
void set(const B &b);
void set(const B *b);
B getB();
C getC();
private:
B *m_b;
C m_c;
};
Sólo se necesita el archivo de inclusión para el tipo C
, debido a la variable miembro m_c
. A menudo también puede eliminar este requisito al no declarar sus variables miembro directamente, pero usando un opaque pointer para ocultar todas las variables miembro en una estructura privada, de modo que ya no aparezcan en el archivo de encabezado.
@mgd - Si tengo un encabezado que tiene 10 incluye y la fuente tiene 10 diferentes incluye, ¿debería mover las inclusiones del encabezado a la fuente para que la fuente tenga 20? –
Ver la respuesta más completa de alex. Una excepción a esto es si tiene encabezados precompilados, en ese caso incluya todos los encabezados de plataforma/framework/OS que nunca se convertirán en un solo archivo e incluya eso en todos lados –