Warum führt das Weglassen von “# include ” nur manchmal zu Kompilierungserrorsn?

Ich bin ein Anfänger mit C ++. Wenn ich den Code schreibe, schreibe ich manchmal #include und der Code funktioniert, manchmal schreibe ich #include nicht und der Code funktioniert nicht. Aber manchmal funktioniert es ohne #include .

Muss ich #include schreiben, damit der Code funktioniert?

   

Wenn Sie Member verwenden, die innerhalb der Standard-Header- string deklariert sind, dann müssen Sie diese Header entweder direkt oder indirekt (über andere Header) einfügen.

Einige Compiler auf einigen Plattformen können zu irgendeiner Zeit des Monats kompiliert werden, obwohl Sie den Header nicht enthalten konnten. Dieses Verhalten ist unglücklich, unzuverlässig und bedeutet nicht, dass Sie den Header nicht einschließen sollten.

Der Grund ist einfach, dass Sie andere Standard-Header eingefügt haben, die auch string . Aber wie gesagt, kann man sich im Allgemeinen nicht darauf verlassen und es kann sich auch sehr plötzlich ändern (wenn zum Beispiel eine neue Version des Compilers installiert wird).

Fügen Sie immer alle notwendigen Header ein. Leider scheint es keine zuverlässige Onlinedokumentation zu geben, auf der Kopfzeilen enthalten sein müssen. Konsultieren Sie ein Buch oder den offiziellen C ++ – Standard.

Zum Beispiel kompiliert der folgende Code mit meinem Compiler ( gcc 4.6):

 #include  int main() { std::string str; } 

Aber wenn ich die erste Zeile entferne, kompiliert es nicht mehr, obwohl der iostream Header eigentlich nicht verwandt sein sollte.

Es ist möglich, dass andere Header, die Sie verwenden , #include .

Dennoch ist es in der Regel eine gute Idee, #include direkt in Ihrem Code zu enthalten, auch wenn dies für einen erfolgreichen Build nicht unbedingt notwendig ist, falls sich diese “anderen” Header ändern – zum Beispiel wegen eines anderen (oder anderen) Compilers / Standard-Bibliothek Implementierung, Plattform oder auch nur eine Build-Konfiguration.

(Diese Diskussion gilt natürlich für jeden Header, nicht nur für .)

Obwohl #include in einer bestimmten Quelldatei nicht direkt vorkommt , heißt das nicht, dass sie nicht in einer anderen Header-Datei enthalten ist. Bedenken Sie:

Datei: header.h

 #if !defined(__HEADER_H__) #define __HEADER_H__ // more here #include  // ...and here #endif 

Datei: source1.cc

 #include  void foo() { // No error here. string s = "Foo"; } 

Datei: source2.cc

 #include 
void bar() { // Still no error, since there's a #include in header.h string s = "Bar"; }

Datei: source3.cc

 void zoid() { // Here's the error; no such thing as "string", since non of the // previous headers had been included. string s = "Zoid"; } 

Wenn Sie nur einen pointers / Verweis auf einen benutzerdefinierten Typ verwenden, muss der Typ nur deklariert werden:

 class my_class; void foo(const my_class& c); 

Aber wenn Sie den Wert verwenden, muss der Compiler die Größe und damit die Definition des Typs kennen.

Und denken Sie daran, dass Standard-Header andere enthalten können, was nicht automatisch bedeutet, dass alle Implementierungen das tun, also können Sie sich nicht darauf verlassen.

Es ist nicht wahr, dass die Header-Zeichenfolge von anderen Headern enthalten ist. Die Header-Zeichenfolge selbst enthält nur Includes. Keine Definitionen. Daher sind alle notwendigen Definitionen, die für die Verwendung von string erforderlich sind, in Headern enthalten, die in der header-Zeichenfolge enthalten sind. Diese Header können bereits von anderen Headern enthalten sein. Dann funktioniert alles. Der Header ios enthält zum Beispiel stringbuf, was beinhaltet …