2008-09-22 16 views
7

Gibt es sowieso ein Objekt einer Klasse zu deklarieren, bevor die Klasse in C++ erstellt wird? Ich frage, weil ich versuche, zwei Klassen zu verwenden, die erste muss eine Instanz der zweiten Klasse enthalten, aber die zweite Klasse enthält auch eine Instanz der ersten Klasse. Ich weiß, dass Sie vielleicht denken, ich könnte in eine Endlosschleife geraten, aber ich muss tatsächlich die zweite Klasse vor der ersten Klasse erstellen und instanzieren.Deklarieren Sie ein Objekt, noch bevor diese Klasse erstellt wird

Antwort

37

Sie können etwas tun:

class A { 
    B b; 
}; 
class B { 
    A a; 
}; 

Das offensichtlichste Problem ist der Compiler nicht weiß, wie zu groß es braucht Klasse A zu machen, weil die Größe von B hängt von der Größe von A!

können Sie aber dies tun:

class B; // this is a "forward declaration" 
class A { 
    B *b; 
}; 
class B { 
    A a; 
}; 

Deklarieren der Klasse B als eine Vorwärts-Deklaration können Sie Zeiger verwenden (und Verweise) zu dieser Klasse, ohne noch die ganze Klassendefinition hat.

5

Sie können keine Instanz einer undefinierten Klasse deklarieren Sie können jedoch einen Zeiger einem erklären:

class A; // Declare that we have a class A without defining it yet. 

class B 
{ 
public: 
    A *itemA; 
}; 

class A 
{ 
public: 
    B *itemB; 
}; 
+0

... oder eine Referenz auf eins: MyClass & rMyObject; –

0

Ist das nah an, was Sie wollen: Die erste Klasse, die zweite Klasse enthält, aber die zweite Klasse (die zuerst erstellt werden soll) hat nur einen Verweis auf die erste Klasse?

+0

Ich versuche tatsächlich das Gegenteil zu tun, wobei die erste Klasse die zweite Klasse referenziert und die zweite Klasse eine Instanz der ersten Klasse enthält. –

0

Dies wird als Querverweis bezeichnet. Siehe here ein Beispiel.

2

Es gibt an elegant solution mit Vorlagen.

template< int T > class BaseTemplate {}; 
typedef BaseTemplate<0> A; 
typedef BaseTemplate<1> B; 
// A 
template<> class BaseTemplate<0> 
{ 
public: 
    BaseTemplate() {} // A constructor 
    B getB(); 
} 

// B 
template<> class BaseTemplate<1> 
{ 
public: 
    BaseTemplate() {} // B constructor 
    A getA(); 
} 

inline B A::getB() { return A(); } 
inline A B::getA() { return B(); } 

Dieser Code wird funktionieren! Also, warum funktioniert es ? Der Grund hat damit zu tun, wie Vorlagen kompiliert werden. Vorlagen verzögern die Erstellung der Funktion Signaturen, bis Sie tatsächlich die Vorlage irgendwo verwenden. Das bedeutet, dass weder getA() noch getB() ihre Signaturen analysiert haben, bis nach beide Klassen A und B bereits vollständig deklariert wurden. Das ist die Magie von diese Methode.

+0

Interessant (obwohl es mehrere Tippfehler enthält). Aber die "getA" und "getB" sind wirklich Fabriken: Sie geben neue Instanzen (nach Wert) zurück. Eine Instanz von A hat keine-A B noch hat eine Instanz von B-eine A. – jwfearn