Ricorda, il preprocessore C / C ++ è una fase di elaborazione separata, puramente testuale. La #include
direttiva estrae il contenuto dell'intestazione inclusa e il compilatore deve analizzarlo. Inoltre, la compilazione di ciascuno .cpp
è completamente separata, quindi il fatto che il compilatore abbia appena analizzato B.h
durante la compilazione B.cpp
non lo aiuta minimamente quando ne ha bisogno di nuovo durante la compilazione A.cpp
. E ancora durante la compilazione C.cpp
. E D.cpp
. E così via. E ciascuno di quei file deve essere ricompilato se uno qualsiasi dei file inclusi è cambiato.
Quindi diciamo che la classe A
usa la classe B
e le classi C
e D
usa la classe A
, ma non è necessario manipolarla B
. Se la classe A
può essere dichiarata solo con la dichiarazione forward di B
, allora B.h
viene compilato due volte: durante la compilazione B.cpp
e A.cpp
(perché B
è ancora necessario all'interno A
dei metodi).
Ma quando A.h
comprende B.h
, viene compilato quattro volte-durante la compilazione B.cpp
, A.cpp
, C.cpp
e D.cpp
come più tardi due ora indirettamente includono B.h
anche.
Anche quando l'intestazione è inclusa più di una volta, il preprocessore deve ancora leggerlo ogni volta. Salterà l'elaborazione del suo contenuto a causa delle protezioni #ifdef
, ma lo legge ancora e deve cercare l'estremità della protezione, il che significa che deve analizzare tutte le direttive del preprocessore all'interno.
(Come menzionato nell'altra risposta, le intestazioni precompilate tentano di aggirare questo problema, ma sono la loro lattina di worm; in pratica puoi ragionevolmente usarle per le intestazioni di sistema e solo se non ne stai usando troppe intestazioni nel tuo progetto)
vehicle.h
,bus.h
,toybus.h
.vehicle.h
includere dabus.h
ebus.h
includere datoybus.h
. quindi se faccio qualche cambiamento inbus.h
. il compilatore si apre e analizza divehicle.h
nuovo? lo compila di nuovo?