Problème étrange est survenu lorsque j'ai essayé de « résoudre » problème de diamant d'habitude de manière habituelle - en utilisant l'héritage virtuel:sous-problème diamant: héritage non multiple dans la branche latérale nécessitent encore constructeur de la classe
A
/\* both virtual
B C
\/
D
Cependant, mon classe de base a ne pas constructeur par défaut, donc je devais l'appeler manuellement D. Cependant, lorsque je tente d'ajouter une classe E dans ce diamant C-hérité
A
/\* both virtual
B C
\/\
D E
il est encore nécessaire pour constructeur appeler de A dans le constructeur E manuellement, c'est-à-dire que C ne sait pas quoi créer A à partir de E même ough il n'y a ni héritage multiple ni diamant A-C-E. Est-il possible de résoudre ce problème sans appeler le constructeur de A à partir de E?
class A
{public:
A (int _N): N(_N) {};
void show()
{cout<<"A"<<N;}
protected:
int N;
};
class B: public virtual A
{ public:
B(int n): A(2*n) {};
void show()
{ cout<<"B"<<N;}
};
class C: public virtual A
{ public:
C(int n): A(3*n) {};
void show()
{ cout<<"C"<<N;}
};
class D: public B,C
{ public:
D(): B(1), C(2), A(3) {};
void show()
{ cout<<"D"<<N;}
};
class E: public virtual C
{ public:
E(): C(1) {};
void show()
{ cout<<"E"<<N;}
};
int main()
{D d; // OK
A *a = &d;
a->show();
E e; // NOT OK, no function A::A() to call in E::E()
A *a2 = &e;
a2->show();
return 0;
}
J'ai besoin de C pour le faire correctement :-).
Ou est-il possible de ne pas essayer de résoudre le problème de diamant du tout:
A A
| | no virtual at all
B C
\/\
D E
et toujours essayer de déclarer objet de la classe D avec deux instances de A mais compilateur dire d'utiliser un C quand Colling de D chaque fois? Lorsque je tente d'ajouter
using C::A
dans la déclaration de D, il produit encore erreur de la base non ambiguë A.
Merci, cela est compréhensible, est-ce que cette signification exacte de l'héritage virtuel? Maintenant, je vois. Probablement je n'ai pas besoin d'héritage virtuel ici, malheureusement ça ne sera pas confortable (car il y a beaucoup de dérivées de E et chacune devrait appeler un constructeur de la même manière que C et ainsi de suite). Peut-être existe-t-il un moyen de contourner le problème du diamant sans héritage virtuel (d'une manière similaire à l'utilisation)? – Nick
@Nick: C'est un peu difficile à dire avec un exemple abstrait comme celui-ci. Pour être honnête, j'évite généralement les hiérarchies d'héritage complexes dans le code que j'écris. Quelqu'un d'autre pourrait avoir une bonne solution pragmatique pour le cas général. –
Je pensais ... eh bien, je n'ai pas besoin que C soit l'enfant de A autant dans mon cas particulier. E pourrait être l'enfant direct de A (avec C) à la place. @James, merci encore beaucoup. – Nick