2008-09-22 8 views
7

Est-il possible de déclarer un objet d'une classe avant la création de la classe en C++? Je demande parce que j'essaye d'employer deux classes, le premier doit avoir une instance de la deuxième classe dedans, mais la deuxième classe contient également une instance de la première classe. Je me rends compte que vous pouvez penser que je pourrais entrer dans une boucle infinie, mais j'ai vraiment besoin de créer et d'instance de la deuxième classe avant le premier cours.Déclarer un objet avant même que cette classe ne soit créée

Répondre

37

Vous ne pouvez pas faire quelque chose comme ceci:

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

Le problème le plus évident est le compilateur ne sait pas grand, il doit faire la classe A, car la taille B dépend de la taille de A!

Vous pouvez cependant faire:

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

Déclarant classe B comme une déclaration avant vous permet d'utiliser des pointeurs (et références) à cette classe sans avoir encore la définition toute la classe.

5

Vous ne pouvez pas déclarer une instance d'une classe non définie mais vous pouvez déclarer un pointeur une:

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

class B 
{ 
public: 
    A *itemA; 
}; 

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

... ou une référence à un: MyClass & rMyObject; –

0

Est-ce à ce que vous voulez: La première classe contient la deuxième classe, mais la deuxième classe (qui doit être créée en premier) a juste une référence à la première classe?

+0

Je suis en train d'essayer de faire l'inverse, où la première classe référence la deuxième classe et la deuxième classe contient une instance de la première classe. –

0

Ceci est appelé référence croisée. Voir here un exemple.

2

Il existe an elegant solution utilisant des modèles.

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(); } 

Ce code fonctionne! Alors, pourquoi fonctionne-t-il? La raison a à voir avec la façon dont les modèles sont compilés. Les modèles retardent la création de la fonction signatures jusqu'à ce que vous utilisiez le modèle quelque part. Cela signifie que ni getA() ni getB() n'aura leurs signatures analysées avant qu'après les deux classes A et B ont déjà été déclarées. C'est la magie de cette méthode.

+0

Intéressant (bien qu'il contienne plusieurs fautes de frappe). Mais le 'getA' et le 'getB' sont vraiment des usines: ils renvoient de nouvelles instances (en valeur). Une instance de A n'a pas de B et une instance de B n'a pas de A. – jwfearn

Questions connexes