Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.
Leí esto aquí. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html .
Entonces dice si una clase (clase A) en el archivo de encabezado no necesita usar la definición real de alguna clase (clase B). En ese momento podemos usar la declaración directa en lugar de incluir el archivo de encabezado particular (clase B).
Pregunta: Si la clase (clase A) en el encabezado if no usa la definición real de una clase particular (clase B), entonces, ¿cómo la declaración directa ayuda a reducir el tiempo de compilación?
fuente
vehicle.h
,bus.h
,toybus.h
.vehicle.h
incluir porbus.h
ebus.h
incluir portoybus.h
. por lo que si hago algún cambio enbus.h
. ¿el compilador se abre y analiza devehicle.h
nuevo? ¿lo compila de nuevo?#pragma once
o#ifndef __VEHICLE_H_
escribir declaraciones en los archivos de encabezado para evitar que dichos archivos se incluyan varias veces (o se usen varias veces al menos en el caso de ifndef).porque entonces A.hpp no necesita #incluir B.hpp
entonces A.hpp se convierte
así que cuando se incluye A.hpp, entonces B.hpp no se incluye implícitamente y no es necesario volver a compilar todos los archivos que dependen solo de A.hpp cada vez que b.hpp cambia
fuente
Recuerde, el preprocesador C / C ++ es un paso de procesamiento separado, puramente textual. La
#include
directiva extrae el contenido del encabezado incluido y el compilador tiene que analizarlo. Por otra parte, la compilación de cada.cpp
es completamente separada, por lo que el hecho de que el compilador solo se analiceB.h
al compilarB.cpp
no lo ayuda lo más mínimo cuando lo necesita nuevamente al compilarA.cpp
. Y de nuevo al compilarC.cpp
. YD.cpp
. Y así. Y cada uno de esos archivos tiene que volver a compilarse si algún archivo incluido en él ha cambiado.Digamos que class
A
usa classB
y classesC
yD
use classA
, pero no necesita manipularB
. Si la claseA
se puede declarar solo con la declaración directa deB
,B.h
se compila dos veces: al compilarB.cpp
yA.cpp
(porqueB
todavía se necesita dentroA
de los métodos).Pero cuando se
A.h
incluyeB.h
, se compila cuatro veces, al compilarB.cpp
,A.cpp
,C.cpp
yD.cpp
como más tarde dos ahora indirectamente incluyenB.h
también.Además, cuando el encabezado se incluye más de una vez, el preprocesador todavía tiene que leerlo cada vez. Omitirá el procesamiento de su contenido debido a la protección
#ifdef
s, pero aún así lo lee y necesita buscar el final de la protección, lo que significa que tiene que analizar todas las directivas del preprocesador en su interior.(Como se mencionó en la otra respuesta, los encabezados precompilados intentan solucionar esto, pero son su propia lata de gusanos; básicamente, puede usarlos razonablemente para los encabezados del sistema y solo si no está usando demasiados, pero no para encabezados en su proyecto)
fuente
Una declaración directa es mucho más rápida de analizar que un archivo de encabezado completo que puede incluir incluso más archivos de encabezado.
Además, si cambia algo en el archivo de encabezado para la clase B, todo, incluido ese encabezado, tendrá que volver a compilarse. Con una declaración de reenvío, ese puede ser solo el archivo fuente en el que reside la implementación de A. Pero si el encabezado de A realmente incluye el encabezado de B, todo incluido
a.hpp
también se recompilará, incluso si no usa nada de B.fuente