Pamiętaj, że preprocesor C / C ++ to osobny, czysto tekstowy etap przetwarzania. Do #include
dyrektywa ściąga treści zawarte nagłówku i kompilator musi ją przeanalizować. Co więcej, kompilacja każdego z nich .cpp
jest całkowicie osobna, więc fakt, że kompilator właśnie przeanalizował B.h
podczas kompilacji B.cpp
, nie pomaga, gdy jest potrzebny ponownie podczas kompilacji A.cpp
. I znowu podczas kompilacji C.cpp
. I D.cpp
… I tak dalej. I każdy z tych plików musi zostać ponownie skompilowany, jeśli jakikolwiek plik w nim się zmienił.
Powiedzmy, że klasa A
używa klasy B
i klas C
i D
używa klasy A
, ale nie trzeba manipulować B
. Jeśli klasa A
może być zadeklarowana za pomocą tylko deklaracji forward B
, niż B.h
jest kompilowana dwukrotnie: podczas kompilacji B.cpp
i A.cpp
(ponieważ B
nadal jest potrzebna w ramach A
metod).
Ale kiedy A.h
obejmuje B.h
, to jest kompilowany cztery razy, podczas kompilacji B.cpp
, A.cpp
, C.cpp
i D.cpp
jak później dwa teraz pośrednio obejmuje B.h
też.
Również, gdy nagłówek jest dołączany więcej niż jeden raz, preprocesor nadal musi go czytać za każdym razem. Pominie przetwarzanie zawartości ze względu na ochronę#ifdef
, ale nadal ją odczytuje i musi szukać końca osłony, co oznacza, że musi przeanalizować wszystkie zawarte w niej dyrektywy preprocesora.
(Jak wspomniano w drugiej odpowiedzi, prekompilowane nagłówki próbują obejść ten problem, ale są one własną puszką robaków; w zasadzie można je rozsądnie wykorzystać do nagłówków systemowych i tylko wtedy, gdy nie używa się ich zbyt wielu, ale nie do nagłówki w twoim projekcie)
vehicle.h
,bus.h
,toybus.h
.vehicle.h
dołącz przezbus.h
ibus.h
dołącz przeztoybus.h
. więc jeśli coś zmieniębus.h
. czy kompilator otwiera się i parsujevehicle.h
ponownie? czy to kompiluje to ponownie?