Ricorda che il preprocessore C / C ++ è un processo di elaborazione separato, puramente testuale. La direttiva #include
estrae il contenuto dell'intestazione inclusa e il compilatore deve analizzarlo. Inoltre, la compilazione di ogni .cpp
è completamente separata, quindi il fatto che il compilatore abbia appena analizzato B.h
durante la compilazione di B.cpp
non lo aiuta di meno quando ne ha bisogno di nuovo durante la compilazione di A.cpp
. E ancora quando si compila C.cpp
. E D.cpp
. E così via. E ciascuno di questi file deve essere ricompilato se qualsiasi file incluso in esso è stato modificato.
Quindi, la classe A
utilizza la classe B
e le classi C
e D
utilizzano la classe A
, ma non è necessario modificare B
. Se la classe A
può essere dichiarata con la dichiarazione forward di B
, allora B.h
viene compilato due volte: quando si compila B.cpp
e A.cpp
(perché B
è ancora necessario nei metodi di A
).
Ma quando A.h
include B.h
, è compilato quattro volte - quando compila B.cpp
, A.cpp
, C.cpp
e D.cpp
come le due successive ora includono indirettamente B.h
.
Anche quando l'intestazione è inclusa più di una volta, il preprocessore deve ancora leggerlo ogni tempo. Salterà l'elaborazione del contenuto a causa della protezione #ifdef
s, ma continua a leggerlo e deve cercare la fine della guardia, il che significa che deve analizzare tutte le direttive del preprocessore all'interno.
(Come accennato nell'altra risposta, le intestazioni precompilate tentano di aggirare questo problema, ma sono le proprie lattine di worm, in pratica si possono usare ragionevolmente per le intestazioni di sistema e solo se non ne si usano troppe, ma non per le intestazioni nel tuo progetto)