Was ist die Beschreibung oder Bedeutung davon: zum Beispiel:
class test;
class test
{
.....
};
Was ist die Beschreibung oder Bedeutung davon: zum Beispiel:
class test;
class test
{
.....
};
C++ (wie C) wurde entwickelt, um von einem Single-Pass-Compiler implementiert werden zu können. Vorwärtsreferenzen sind in Fällen notwendig, in denen der Compiler wissen muss, dass ein Symbol auf eine Klasse verweist, bevor die Klasse tatsächlich definiert ist. Das klassische Beispiel hierfür ist, wenn zwei Klassen Zeiger aufeinander enthalten müssen, z.B.
class B;
class A {
B* b;
};
class B {
A* a;
};
Ohne den Vorwärtsverweis auf B konnte der Compiler die Definition für A nicht erfolgreich parsen, und Sie können das Problem nicht beheben, indem Sie die Definition von B vor A einfügen.
In einer Sprache wie C#, die einen Two-Pass-Compiler benötigt, braucht man keine Vorwärtsreferenzen
class A {
B b;
}
class B {
A a;
}
weil der erste Durchlauf des Compilers einfach alle Symboldefinitionen aufnimmt. Beim zweiten Durchlauf kann der Compiler sagen: "Ich weiß, dass B eine Klasse ist, weil ich die Definition beim ersten Durchlauf gesehen habe".
Der Compiler benötigt die Definition einer Klasse, wenn auf Mitglieder/Methoden dieser Klasse zugegriffen wird oder wenn die Größe bekannt sein muss. In anderen Fällen ist eine Vorwärtsdeklaration ausreichend. Dadurch sparen Sie Kompilierzeit. Beispiel:
class A {
B m_b;
C* m_ptrC;
};
Für diese Klasse benötigen Sie die Definition von B (Größe erforderlich) und nur die Deklaration von C (Zeiger haben eine feste Größe). Sie müssen nur den Header von B einbinden, nicht den von C. Eine Forward-Deklaration von C ist ausreichend.
a.h:
#ifndef A_H
#define A_H
#include <b.h>
class C;
class A
{
B m_b;
C* m_ptrC;
}
#endif
Die Vorwärtsdeklaration von c (anstatt c.h einzuschließen, was auch möglich ist) erspart Ihnen das Parsen von c.h, wenn Sie a.h einschließen. Bei einem großen Projekt kann dies eine Menge Kompilierzeit einsparen. Ein weiterer Vorteil ist, dass Änderungen in c.h in diesem Fall keine Neukompilierung für a auslösen. Ich weiß nicht, ob der Compiler dies erkennt, wenn man c.h einbindet, anstatt es vorwärts zu deklarieren.
Weitere Informationen erhalten Sie, wenn Sie versuchen, das Pimpl-Diom zu verstehen (googeln Sie einfach danach. Sie werden eine Menge Treffer erhalten).
Natürlich - in a.cpp, wenn Sie tatsächlich etwas mit dem Zeiger auf c tun (z.B. m_ptrC->Add()), müssen Sie c.h einbinden. Aber a.cpp wird nur einmal gelesen, während die Header-Datei n-mal gelesen wird, mit großem n für Klassen, die sehr oft in großen Projekten verwendet werden.
Die Forward-Deklaration ermöglicht auch zirkuläre Abhängigkeiten. Beispiel:
class B;
class A {
B* m_ptrB;
}
class B {
A* m_ptrA;
}
Denken Sie nur daran, dass Sie keine Informationen über Größe und Methoden verwenden können, wenn Sie Forward-Deklarationen verwenden. Dies ist auch der Fall bei 2 Klassen, die sich gegenseitig einschließen (eine Klasse braucht den Vorwärtsverweis jedoch nicht). Ich persönlich halte zirkuläre Referenzen für einen schlechten Stil und sollte sie nach Möglichkeit vermeiden.
Für weitere Informationen: C++ FAQ
Vielen Dank für den Hinweis auf die zirkulären Abhängigkeiten, ich hatte sie einfach vergessen.
Erstens, die Klasse ist erklärt dann ist es definiert .
Erklärung: Sie teilt dem Compiler lediglich mit: Ok, hier ist etwas (Methode, Klasse, etc.), das unter dem angegebenen Namen verwendet werden kann. Sie sagt nur bindet den gegebenen Namen zu etwas.
Definition: Sie teilt dem Compiler mit: Ok, hier steht, was (und wie) die Methoden, Klassen usw. tatsächlich ihre Arbeit tun. Wenn etwas definiert ist, dann wird der Compiler veranlasst, tatsächlich zuordnen. Platz für sie.
Schauen Sie doch mal unter ici .
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.