Ricorda, il preprocessore C / C ++ è una fase di elaborazione separata, puramente testuale. La #includedirettiva 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.hdurante la compilazione B.cppnon 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 Ausa la classe Be le classi Ce Dusa la classe A, ma non è necessario manipolarla B. Se la classe Apuò essere dichiarata solo con la dichiarazione forward di B, allora B.hviene compilato due volte: durante la compilazione B.cppe A.cpp(perché Bè ancora necessario all'interno Adei metodi).
Ma quando A.hcomprende B.h, viene compilato quattro volte-durante la compilazione B.cpp, A.cpp, C.cppe D.cppcome più tardi due ora indirettamente includono B.hanche.
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.hincludere dabus.hebus.hincludere datoybus.h. quindi se faccio qualche cambiamento inbus.h. il compilatore si apre e analizza divehicle.hnuovo? lo compila di nuovo?