2010-03-06 9 views
3

Je suis assez nouveau à l'utilisation de C++ et je suis réellement arrêté à un problème.Référence de la classe au parent

J'ai une classe A, B, C défini comme suit (pseudocode)

class A 
{ 
... 
    DoSomething(B par1); 
    DoSomething(C par1); 
... 
} 

class B 
{ 
    A parent; 
... 
} 

class C 
{ 
    A parent; 
... 
} 

Le problème est:

Comment faire cela? Si je le fais simplement (comme je l'ai toujours fait en C#) ça donne des erreurs. Je comprends à peu près la raison de ceci. (A n'est pas déjà déclaré si j'ajoute la référence (include) de B et C dans son propre en-tête)

Un moyen de contourner ce problème? (Avec pointeur void * n'est pas la voie à suivre IMHO)

+0

Souhaitez-vous que A soit la classe parent de B et C? –

+0

Autre chose: vous n'avez vraiment pas de * référence * pour parent dans B et C. Si vous faites: 'A a; B b (a); C c (a); 'alors il y aura trois instances A non liées, pas une instance avec deux objets s'y référant. Si c'est ce que vous voulez plutôt utiliser un membre pointeur-à-un. – UncleBens

Répondre

5

Forward-declareB et C. De cette façon, le compilateur saura qu'ils existent avant d'atteindre la définition de la classe A.

class B; 
class C; 

// At this point, B and C are incomplete types: 
// they exist, but their layout is not known. 
// You can declare them as function parameters, return type 
// and declare them as pointer and reference variables, but not normal variables. 
class A 
{ 
    .... 
} 

// Followed by the *definition* of B and C. 

PS

Plus, une astuce sans rapport avec la question (voir comment vous venez d'un arrière-plan C#): it's better to pass by const reference than by value:

class A 
{ 
... 
    void DoSomething(const B& par1); 
    void DoSomething(const C& par1); 
... 
} 
1

utilisation déclaration avant

Vous pouvez définir la classe A; sans elle est mise en œuvre, avant B et C, puis définir ultérieurement

2

Vous devez envoyer déclarer des classes B et C avant A:

class B; 
class C; 

class A { 
    ... 
}; 

Au point où B et C sont référencées dans les A, le compilateur seulement besoin de savoir quel genre d'animaux ce sont. Avec la déclaration forward, vous satisferez le compilateur. Puis plus tard, vous pouvez les définir correctement.

+0

+1 pour le point-virgule après la définition de la classe! –

3

Pour les déclarations de fonction, les types de paramètres sont autorisés à être incomplètes si la fonction est définie pas là:

class B; 
class C; 

class A 
{ 
... 
    R DoSomething(B par1); 
    R DoSomething(C par1); 
... 
} 

class B 
{ 
    A parent; 
... 
} 

class C 
{ 
    A parent; 
... 
} 

inline R A::DoSomething(B par1) { ... } 
inline R A::DoSomething(C par1) { ... } 

donc les définiriez-vous juste après B et C devenir complète. Mais comme ils sont définis en dehors de la classe, faites-les inline afin que plusieurs définitions dans différentes unités de traduction ne causent pas d'erreurs de liens.

+0

Assurez-vous également que vous voulez vraiment copier les paramètres. Selon vos besoins, _maybe_ en les passant par référence, comme DoSomething (B & par1) serait le meilleur. – rotoglup