Existe-t-il un moyen (pratique) de contourner l'ordre d'appel du constructeur normal (virtuel)?Appel du constructeur surchargé d'une classe de base virtuelle
Exemple:
class A
{
const int i;
public:
A()
: i(0)
{ cout << "calling A()" << endl; }
A(int p)
: i(p)
{ cout << "calling A(int)" << endl; }
};
class B
: public virtual A
{
public:
B(int i)
: A(i)
{ cout << "calling B(int)" << endl; }
};
class C
: public B
{
public:
C(int i)
: A(i), B(i)
{ cout << "calling C(int)" << endl; }
};
class D
: public C
{
public:
D(int i)
: /*A(i), */ C(i)
{ cout << "calling D(int)" << endl; }
};
int main()
{
D d(42);
return 0;
}
sortie:
appelant A()
appelant B (int)
appelant C (int)
appelant D (int)
Ce que je veux avoir est quelque chose comme:
appelant A (int)
appelant B (int)
appelant C (int)
appelant D (int)
Comme vous le voyez, il y a un héritage virtuel impliqué, ce qui amène le constructeur de D à appeler le constructeur de A en premier, mais comme aucun paramètre n'est fourni, il appelle A(). Il y a le const int qui a besoin d'initialisation, donc j'ai un problème. Ce que je voudrais faire est de cacher les détails d'héritage de C, c'est pourquoi je cherche un moyen d'éviter d'appeler A (i) dans la liste d'initialisation du constructeur de D (et de chaque dérivé). [edit] Dans ce cas précis, je peux supposer qu'il n'y a que des classes enfants non-virtuelles à héritage unique de C (comme D en est une). [/ Edit]
[modifier]
classes de base virtuelles sont initialisés avant toutes les classes de base non virtuelles sont initialisés, alors que la classe la plus dérivée peut initialiser les classes de base virtuelles. - James McNellis
C'est exactement le point, je ne le font pas veulent la classe la plus dérivée pour appeler le constructeur de la classe de base virtuelle. [/ modifier]
la situation suivante (pas représenté dans l'exemple de code ci-dessus):
A
/\
B0 B1
\/
C
|
D
Je comprends pourquoi C doit appeler le cteur de A (ambiguïté) lorsque vous instancier C, mais pourquoi D doit-il l'appeler lors de l'instanciation de D?
Je ne crois pas que votre exemple de code corresponde à la sortie que vous fournissez. Êtes-vous sûr d'instancier avec l'instruction "D d"? ? –
sry, j'ai oublié le paramètre .... c'est D d (42) maintenant. Merci. – dyp
Ok, cela semble plus juste :-) Puis-je vous demander pourquoi vous voulez utiliser l'architecture "diamant redouté"? Tu ne peux pas réorganiser ton code d'une autre manière? –