Organizacja plików nagłówkowych klasy C++

Jakie są wytyczne dotyczące kodowania i organizacji plików w C++, które proponujesz osobom, które mają do czynienia z wieloma współzależnymi klasami rozłożonymi na kilka plików źródłowych i nagłówkowych?

Mam taką sytuację w moim projekcie i rozwiązywanie błędów związanych z definicjami klas przejście przez kilka plików nagłówkowych stało się dość bolesne.

Author: Don Kirkby, 2008-12-06

6 answers

Niektóre ogólne wytyczne:

  • Połącz swoje interfejsy z implementacjami. Jeśli masz foo.cxx, wszystko tam zdefiniowane powinno być zadeklarowane w foo.h.
  • upewnij się, że każdy plik nagłówka #zawiera wszystkie inne niezbędne nagłówki lub deklaracje forward niezbędne do niezależnej kompilacji.
  • oprzyj się pokusie tworzenia nagłówka "wszystko". Zawsze są kłopotami.
  • umieścić zestaw powiązanych (i współzależnych) funkcjonalności w jednym pliku. Java i inne środowiska zachęcają do tworzenia jednej klasy na każdy plik. W C++ często potrzebujesz jednego zestawu klas na plik. To zależy od struktury Twojego kodu.
  • preferuj forward declaration zamiast #includeS, O ile to możliwe. Pozwala to na zerwanie cyklicznych zależności nagłówka. Zasadniczo, w przypadku cyklicznych zależności między oddzielnymi plikami, potrzebny jest wykres zależności plików, który wygląda mniej więcej tak:
    • A.cxx wymaga A.h i B.h
    • B.cxx wymaga A.h i B.h
    • A.h wymaga B.h
    • B.h jest niezależna (i forward-deklaruje klasy zdefiniowane w A.h)

Jeśli twój kod ma być biblioteką używaną przez innych programistów, należy wykonać kilka dodatkowych kroków:]}

  • w razie potrzeby użyj pojęcia "prywatne nagłówki". Czyli pliki nagłówkowe, które są wymagane przez kilka plików źródłowych, ale nigdy nie są wymagane przez publiczny interfejs. Może to być plik ze wspólnymi funkcjami wbudowanymi, makrami lub stałymi wewnętrznymi.
  • oddziel swój publiczny interfejs od prywatnej implementacji na poziomie systemu plików. Zazwyczaj używam podkatalogów include/ i src/ w moich projektach C lub c++, gdzie include/ ma wszystkie moje nagłówki publiczne, a src/ ma wszystkie moje źródła. i prywatne nagłówki.
Polecam znaleźć kopię książki Johna Lakosa wielkoskalowe Projektowanie oprogramowania C++ . To jest całkiem niezła książka, ale jeśli przejrzysz jego dyskusje na temat architektury fizycznej, wiele się nauczysz.
 65
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-06 08:35:56

Sprawdź standardy kodowania C i C++ w NASA Goddard Space Flight Center . Jedyną regułą, którą szczególnie odnotowałem w standardzie C i przyjąłem w moim własnym kodzie, jest ta, która wymusza "samodzielny" charakter plików nagłówkowych. W pliku wdrożenia xxx.cpp w przypadku nagłówka xxx.h upewnij się, że xxx. h jest pierwszym nagłówkiem. Jeśli nagłówek nie jest samowystarczalny w dowolnym momencie, kompilacja nie powiedzie się. Jest to pięknie proste i skuteczne zasada.

Jedyny raz, gdy zawiedzie to port pomiędzy maszynami, a nagłówek xxx. h zawiera, powiedzmy, <pqr.h>, ale <pqr.h> wymaga urządzeń, które są udostępniane przez nagłówek <abc.h> na oryginalnej platformie( więc <pqr.h> zawiera <abc.h>), ale urządzenia nie są udostępniane przez <abc.h> na drugiej platformie (są w def.h zamiast, ale <pqr.h> nie zawiera <def.h>). Nie jest to wina reguły, a problem jest łatwiej zdiagnozowany i naprawiony, jeśli zastosujesz się do zasada.

 8
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-06 11:11:25

Sprawdź sekcję pliku nagłówkowego w Google style guide

 6
Author: yesraaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-13 03:28:38

Odpowiedź Toma jest doskonała!

Jedyną rzeczą, którą bym dodał jest to, aby nigdy nie mieć "using declarations" w plikach nagłówkowych. Powinny być dozwolone tylko w plikach implementacyjnych, np. foo.cpp.

Logika tego jest dobrze opisana w doskonałej książce " Accelerated C++ "(Amazon link - sanitiated for script kiddie link)

 5
Author: Rob Wells,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:25

Jeszcze jeden punkt oprócz innych tutaj:

Nie dołączaj żadnych prywatnych definicji w pliku nagłówkowym. Np. wszelkie definicja, która jest używana tylko w xxx.cpp powinno być w xxx.cpp, nie xxx. h.

Wydaje się oczywiste, ale widzę to często.

 3
Author: Steve Fallows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-07 21:58:16

Chciałbym dodać jedną bardzo dobrą praktykę (zarówno w C jak i C++), która często jest pomijana:

Foo.c

#include "foo.h" // always the first directive

Wszelkie inne potrzebne nagłówki powinny następować, a następnie kodować. Chodzi o to, że prawie zawsze potrzebujesz nagłówka dla tej jednostki kompilacyjnej i włączenie go jako pierwszej dyrektywy gwarantuje, że nagłówek pozostanie samowystarczalny (jeśli nie, będą błędy). Dotyczy to zwłaszcza nagłówków publicznych.

Jeśli w którymś momencie musisz umieścić coś przed tym włączenie nagłówka (oczywiście z wyjątkiem komentarzy), wtedy prawdopodobnie robisz coś złego. Chyba, że naprawdę wiesz, co robisz... co prowadzi do kolejnej ważniejszej Zasady = > komentuj swoje hacki !

 3
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-30 07:04:52