Dies ist eine dieser Arten von Codierungsstandards, die eher "sollten" als "sollen". Der Grund ist, dass Sie so ziemlich einen C ++ - Parser schreiben müssten, um ihn durchzusetzen.
Eine sehr häufige Regel für Header-Dateien ist, dass sie für sich selbst stehen müssen. Eine Header-Datei darf nicht erfordern, dass einige andere Header-Dateien # eingeschlossen werden, bevor der betreffende Header aufgenommen wird. Dies ist eine überprüfbare Anforderung. Bei einem zufälligen Header foo.hh
sollte Folgendes kompiliert und ausgeführt werden:
#include "foo.hh"
int main () {
return 0;
}
Diese Regel hat Konsequenzen hinsichtlich der Verwendung anderer Klassen in einigen Headern. Manchmal können diese Konsequenzen vermieden werden, indem diese anderen Klassen vorwärts deklariert werden. Dies ist bei vielen Standardbibliotheksklassen nicht möglich. Es gibt keine Möglichkeit, eine Vorlageninstanziierung wie std::string
oder weiterzuleiten std::vector<SomeType>
. Sie müssen #include
diese STL-Header im Header verwenden, auch wenn der Typ nur als Argument für eine Funktion verwendet wird.
Ein weiteres Problem betrifft Dinge, die Sie zufällig hineinziehen. Beispiel: Beachten Sie Folgendes:
Datei foo.cc:
#include "foo.hh"
#include "bar.hh"
void Foo::Foo () : bar() { /* body elided */ }
void Foo::do_something (int item) {
...
bar.add_item (item);
...
}
Hier bar
ist ein Klassendatenelement Foo
vom Typ Bar
. Sie haben hier das Richtige getan und #included bar.hh, obwohl dies in dem Header enthalten sein müsste, der die Klasse definiert Foo
. Sie haben jedoch die von Bar::Bar()
und verwendeten Inhalte nicht berücksichtigt Bar::add_item(int)
. Es gibt viele Fälle, in denen diese Aufrufe zu zusätzlichen externen Referenzen führen können.
Wenn Sie foo.o
mit einem Tool wie analysieren nm
, wird angezeigt, dass die Funktionen in foo.cc
alle Arten von Dingen aufrufen, für die Sie nicht die entsprechenden Schritte ausgeführt haben #include
. Sollten Sie also #include
Anweisungen für diese zufälligen externen Referenzen hinzufügen foo.cc
? Die Antwort ist absolut nicht. Das Problem ist, dass es sehr schwierig ist, die Funktionen, die zufällig aufgerufen werden, von denen zu unterscheiden, die direkt aufgerufen werden.