2008-11-21 10 views
7

Ich versuche, eine Klasse B innerhalb einer Klasse zu deklarieren und verwenden A und definieren B außerhalb A.
Ich weiß für eine Tatsache, dass dies möglich ist, weil Bjarne Stroustrup
diese verwendet in sein Buch "Die C++ Programmiersprache"
(Seite 293, zum Beispiel die String-und Srep-Klassen).C++ Verschachtelte Klassen Vorwärtsdeklaration Fehler

Das ist also mein minimal Stück Code, das Problem

class A{ 
struct B; // forward declaration 
B* c; 
A() { c->i; } 
}; 

struct A::B { 
/* 
* we define struct B like this becuase it 
* was first declared in the namespace A 
*/ 
int i; 
}; 

int main() { 
} 

Dieser Code gibt die folgende Zusammenstellung von Fehlern in g ++ Ursachen:

tst.cpp: In constructor ‘A::A()’: 
tst.cpp:5: error: invalid use of undefined type ‘struct A::B’ 
tst.cpp:3: error: forward declaration of ‘struct A::B’ 

ich in dem C++ FAQ zu schauen versucht und den genähert Ich habe here und here aber
diejenigen, die nicht auf meine Situation zutreffen.
Ich auch read this von hier, aber es löst nicht mein Problem.

Beiden gcc und MSVC 2005 geben Compiler-Fehler auf diesen

Antwort

11

Definieren Sie den Konstruktor für A nach der Definition von struct B.

+0

ja, das hat funktioniert danke :) – xxxxxxx

+0

Gern geschehen! :-) –

+1

Der Konstruktor wird definiert, nachdem B deklariert wurde. Es muss definiert werden, nachdem B definiert wurde. –

15

Den Ausdruck c->i dereferenziert der Zeiger auf struct A::B so eine vollständige Definition an diesem Punkt im Programm sichtbar sein muss.

Die einfachste Lösung ist, den Konstruktor von A nichtlinear zu machen und nach der Definition von struct A::B einen Körper dafür zu liefern.

+0

Oder definieren Sie die Funktion als Inline mit dem Schlüsselwort 'inline' nach der Definition von Struktur B. – Phlucious

7

Dies ist ein gutes Beispiel dafür, warum Sie wollen Definitionen von Erklärungen getrennt zu halten. Sie müssen die Reihenfolge der Dinge so ändern, dass der Konstruktor A::A() nach der Definition von struct A::B definiert wird.

class A 
{ 
    struct B; 
    B* c; 
    A(); 
}; 

struct A::B 
{ 
    int i; 
}; 

A::A() { c->i; } 

int main() 
{ 
    return 0; 
}
1

Interessanterweise habe ich in das gleiche Problem mit der Seite 293 ('11 .12 A String-Klasse) im Stroustrup Buch erwähnt gestoßen.

Das Beispiel in der gedruckten Buches vorgesehen scheint Schuld zu sein, die folgenden Methoden als Inline-Bereitstellung, anstatt sie nach der Definition von struct Srep definieren

class String { 
    // ... 
    void check(int i) const { if (i<0 || rep->sz <=i) throw Range(); } 
    char read(int i) const { return rep->s[i]; } 
    void write(int i, char c) { rep=rep->get_own_copy(); rep->s[i]=c; } 
    ...etc... 

ich ein wenig gegoogelt und fand die Autoren neueste Implementierung dieser String-Klasse, hier verfügbar:

Er scheint es geändert zu haben, so dass diese Methoden nicht mehr inline sind, um das Problem zu vermeiden, das in diesem Thread erwähnt wird.

Verwandte Themen