Odpowiedź: Niech A.h
obejmują b.h
, c.h
i d.h
tylko wtedy, gdy jest to potrzebne do spraw, aby kompilacja się udała. Zasada jest taka: w razie potrzeby uwzględnij tylko tyle kodu w pliku nagłówkowym. Wszystko, co nie jest natychmiast potrzebne w A.h
, powinno być dołączone przez A.cpp
.
Uzasadnienie: Im mniej kodu jest zawarty w plikach nagłówkowych, tym mniej prawdopodobne jest, że będziesz musiał przekompilować kod, który używa pliku nagłówka po przeprowadzeniu jakiejś zmiany. Jeśli istnieje wiele odniesień #include
między różnymi plikami nagłówkowymi, zmiana któregokolwiek z nich będzie wymagać przebudowy wszystkich innych innych plików zawierających zmieniony plik nagłówkowy - rekursywny. Więc jeśli zdecydujesz się dotknąć jakiegoś pliku nagłówkowego, może to odbudować ogromne części twojego kodu.
Używając w swoich plikach nagłówkowych forward declarations, redukujesz sprzężenie plików źródłowych, dzięki czemu kompozycja staje się szybsza. Takie deklaracje forward mogą być używane w wielu sytuacjach więcej niż mogłoby się wydawać. Jako zasada, trzeba plik nagłówka t.h
(która definiuje typ T
) jeśli
- Zadeklaruj zmienną składową typu
T
(uwaga, to nie ma zawierać deklarowania pointer-to-tylko T
).
- Napisz niektóre funkcje wbudowane, które mają dostęp do elementów obiektu typu
T
.
Robisz nie potrzebę włączenia deklarację T
jeśli plik header tylko
- Deklaruje konstruktorzy/funkcje, które biorą odniesienia lub odsyłacze do
T
obiektu. Deklaracja funkcji zwracających obiekt T
za pomocą wskaźnika, odwołania lub wartości.
- Deklaracja zmiennych składowych, które są odniesieniami lub wskaźnikami do obiektu
T
.
Rozważ tę deklarację klasową; które pliki należą do A
, B
i C
czy naprawdę trzeba dołączyć ?:
class MyClass
{
public:
MyClass(const A &a);
void set(const B &b);
void set(const B *b);
B getB();
C getC();
private:
B *m_b;
C m_c;
};
Wystarczy include pliku dla danego typu C
, z powodu zmiennej składowej m_c
. Często można również usunąć ten wymóg, nie deklarując bezpośrednio zmiennych członkowskich, ale za pomocą opaque pointer, aby ukryć wszystkie zmienne składowe w strukturze prywatnej, tak aby nie pojawiały się już w pliku nagłówkowym.
@mgd - Jeśli mam nagłówek, który ma 10 obejmuje, a źródło ma 10 różnych obejmuje, powinienem po prostu przenieść obejmuje z nagłówka do źródła, więc źródło ma 20 obejmuje? –
Zobacz bardziej kompletną odpowiedź alex. Jednym z wyjątków jest to, że jeśli masz prekompilowane nagłówki, to w tym przypadku wszystkie nagłówki platformy/frameworka/OS, które nigdy nie zmienią się w jeden plik i zawierają go wszędzie. –