Include-Guards bieten Schutz vor rekursiver Inklusion, aber sie Abhängigkeiten zwischen Datenstrukturdefinitionen in sich gegenseitig einschließenden Headern können nicht verhindert werden. Betrachten Sie den folgenden Code:
// header.h #ifndef HEADER_H #define HEADER_H class A; class B { public: A* pA; }; #endif // HEADER_H
// source1.cpp #include "header.h" A* aPtr = new A;
// source2.cpp #include "header.h" B* bPtr = new B;
In diesem Szenario enthält source1.cpp header.h, das source2.cpp (indirekt) enthält. Dieses Verhalten wird durch Include-Guards verhindert, aber der Compiler meldet trotzdem einen Fehler, da Klasse A nicht in header.h definiert ist.
Um dieses Problem zu lösen, können Vorwärtsdeklarationen in header.h verwendet werden:
// header.h #ifndef HEADER_H #define HEADER_H struct A; class B { public: A* pA; }; #endif // HEADER_H
Dadurch wird sichergestellt, dass der Compiler sich der Existenz der Klasse A bewusst ist, ohne deren Definition anzugeben.
Einschließliche Schutzvorrichtungen verhindern mehrere Symboldefinitionen innerhalb derselben Übersetzungseinheit (.cpp-Datei). Sie schützen jedoch nicht vor mehreren Definitionen über separate Übersetzungseinheiten hinweg.
Betrachten Sie den folgenden Code:
// header.h #ifndef HEADER_H #define HEADER_H int f() { return 0; } #endif // HEADER_H
// source1.cpp #include "header.h" int main() { f(); }
// source2.cpp #include "header.h" int main() { f(); }
In diesem Beispiel ist die Funktion f() ist in header.h definiert. Wenn source1.cpp und source2.cpp separat kompiliert werden, verhindern die Include-Schutzvorrichtungen mehrere Definitionen innerhalb jeder Übersetzungseinheit. Wenn der Objektcode jedoch miteinander verknüpft wird, erkennt der Linker mehrere Definitionen von f().
Um dieses Problem zu lösen, kann das Schlüsselwort „inline“ verwendet werden, um den Compiler anzuweisen, die Funktionsdefinition direkt am zu integrieren Aufrufseite:
// header.h #ifndef HEADER_H #define HEADER_H inline int f() { return 0; } #endif // HEADER_H
Alternativ kann die Funktionsdefinition in eine separate .cpp-Datei verschoben werden, um Konflikte mit den Definitionen in anderen Übersetzungseinheiten zu vermeiden.
Das obige ist der detaillierte Inhalt vonWarum können Include-Guards die rekursive Einbeziehung und mehrere Symboldefinitionen nicht verhindern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!