Ich habe ein scheinbar einfaches und unkompliziertes Codesegment, das eine vereinfachte Version eines Problems ist, das ich in einem Spiel hatte, das ich schreibe. Ich versuche, ein statisches Feld in einer Klasse von meiner Hauptmethode auf einen anderen Wert zu setzen. Dieser Code wird jedoch nicht und ich verstehe nicht warum.
Ich bekomme den Fehler
1>Source.obj : error LNK2001: Unresolved external symbol “public: static class A * B::a” (?a@B@@2PAVA@@A)
class A
{
public:
A()
{
}
};
class B
{
public:
static A* a;
};
int main()
{
B::a = new A;
}
Was besagt die Regel, dass ich mein statisches Klassenmitglied außerhalb der Klasse definieren muss, um es zu verknüpfen?
Wie aus deinem Kommentar hervorgeht
aber was ist die Regel, die das definiert?
Von dem C++-Referenz es sagt
Definitionen und ODR
Definitionen sind Deklarationen, die die durch die Deklaration eingeführte Entität vollständig definieren. Jede Deklaration ist eine Definition, mit Ausnahme der folgenden:
…
- Deklaration eines statischen Datenmembers innerhalb einer Klassendefinition
struct S { // defines S
int n; // defines S::n
static int i; // declares, but doesn't define S::i
};
int S::i = 0; // defines and initializes S::i
Als zusätzliche Referenz können Sie auch hier nachsehen Wikipedia, Eine Definitionsregel
Ich habe endlich den Strom gefunden (2. Juni 2014) neueste frei verfügbare Standardreferenz (eine Kopie des aktuell veröffentlichten Standards ist für etwa 30 $ erhältlich, glaube ich):
§ 9.4.2
2 Die Deklaration eines statischen Datenmembers in seiner Klassendefinition ist keine Definition und kann von einem anderen unvollständigen Typ als cv-qualified void sein. Die Definition für ein statisches Datenelement muss in einem Namensraumbereich erscheinen, der die Klassendefinition des Elements einschließt. In der Definition im Gültigkeitsbereich des Namensraums muss der Name des statischen Datenelements durch seinen Klassennamen unter Verwendung des Operators :: qualifiziert werden. Der Initialisierungsausdruck in der Definition eines statischen Datenmembers liegt im Gültigkeitsbereich seiner Klasse
Sie haben das statische Datenelement nicht definiert. Sie haben es nur in der Klassendefinition deklariert. Fügen Sie die folgende Zeile hinzu
A * B::a;
vor der Hauptsache.
Oder Sie könnten es mit dem Operator new initialisieren.
A * B::a = new A;
Zu deiner Frage
Was besagt die Regel, dass ich mein statisches Klassenmitglied außerhalb der Klasse definieren muss, um es zu verknüpfen?
dann gemäß Absatz #2 von Abschnitt 9.4.2 Statische Datenmember des C++-Standards
2 Die Deklaration eines statischen Datenmembers in seiner Klassendefinition ist keine Definition und kann von einem anderen unvollständigen Typ als CV-Qualified Void sein. Die Definition für ein statisches Datenelement muss in einem Namensraumbereich erscheinen, der die Klassendefinition des Elements einschließt.
Du brauchst
A* B::a;
außerhalb der Klasse.– David G
1. Juni 2014 um 20:01 Uhr
warum sollte ich das tun?
– Popgalopp
1. Juni 2014 um 20:02 Uhr
@popgalop ‘Warum sollte ich das tun?’ Denn das sind die Regeln der Sprache.
– πάντα ῥεῖ
1. Juni 2014 um 20:05 Uhr
aber was ist die Regel, die das definiert
– Popgalopp
1. Juni 2014 um 20:05 Uhr
Falls es hilft: 9.4.2. (:p)
– Abweichler
1. Juni 2014 um 20:21 Uhr