Este es uno de esos "debería" en lugar de "debe" tipos de estándares de codificación. La razón es que tendría que escribir un analizador C ++ para aplicarlo.
Una regla muy común para los archivos de encabezado es que deben estar solos. Un archivo de encabezado no debe requerir que algunos otros archivos de encabezado estén #incluidos antes de incluir el encabezado en cuestión. Este es un requisito comprobable. Dado un encabezado aleatorio foo.hh
, se debe compilar y ejecutar lo siguiente:
#include "foo.hh"
int main () {
return 0;
}
Esta regla tiene consecuencias con respecto al uso de otras clases en algún encabezado. A veces, esas consecuencias pueden evitarse declarando hacia adelante esas otras clases. Esto no es posible con muchas de las clases de biblioteca estándar. No hay forma de reenviar declarar una instancia de plantilla como std::string
o std::vector<SomeType>
. Tienes que #include
esos encabezados STL en la cabecera incluso si el único uso del tipo es como un argumento a una función.
Otro problema es con cosas que incidentalmente arrastra. Ejemplo: considere lo siguiente:
archivo foo.cc:
#include "foo.hh"
#include "bar.hh"
void Foo::Foo () : bar() { /* body elided */ }
void Foo::do_something (int item) {
...
bar.add_item (item);
...
}
Aquí bar
hay un Foo
miembro de datos de clase que es de tipo Bar
. Has hecho lo correcto aquí y has #incluido bar.hh aunque eso debería haberse incluido en el encabezado que define la clase Foo
. Sin embargo, no ha incluido las cosas utilizadas por Bar::Bar()
y Bar::add_item(int)
. Hay muchos casos en los que estas llamadas pueden generar referencias externas adicionales.
Si analiza foo.o
con una herramienta como nm
, parecerá que las funciones foo.cc
están llamando a todo tipo de cosas para las que no ha hecho lo apropiado #include
. Entonces, ¿debería agregar #include
directivas para esas referencias externas incidentales foo.cc
? La respuesta es absolutamente no. El problema es que es muy difícil distinguir aquellas funciones que se llaman incidentalmente de las que se llaman directamente.