2010-08-19 8 views
16

Est-il possible d'avoir un héritage virtuel pour la classe ne fournissant pas le constructeur par défaut?Constructeur par défaut et héritage virtuel

Le présent diagramme en diamant (le plus simple avec le seul changement de constructeur par défaut non fourni) ne compile pas (g ++ 4.4.3).

class A { 
public: 
    A(int) {} 
}; 
class B : virtual public A { 
public: 
    B(int i) : A(i) {} 
}; 
class C : virtual public A { 
public: 
    C(int i) : A(i) {} 
}; 
class D : public B, public C { 
public: 
    D(int i) : B(i), C(i) {} 
}; 

Merci, Francesco

Répondre

3

Je crois que votre classe D a également besoin d'appeler explicitement le constructeur de A dans sa liste de initialiseur.

22

Vous devez appeler le constructeur de A explicitement ici

D(int i) : A(i), B(i), C(i) {} 

classes de base virtuelles sont spéciales en ce qu'elles sont initialisés par la classe la plus dérivée et non par toutes les classes de base intermédiaires qui hérite du virtuel base. Lequel des initiateurs multiples potentiels serait le bon choix pour initialiser la base?

Si la classe la plus dérivée en construction ne la liste pas dans sa liste d'initialisation de membre, alors la classe de base virtuelle est initialisée avec son constructeur par défaut qui doit exister et être accessible.

copié sans vergogne de here :-)

1

L'article Dr. Dobbs Multiple Inheritance Considered Useful explique différentes façons de traiter cette question. La recommandation consiste essentiellement à fournir des constructeurs par défaut et des méthodes init(). Il ajoute plus de travail pour B et C, mais empêche D d'avoir à savoir sur A.

+1

Laissant D ignorer A est, bien sûr, souhaitable. La solution 'init()' a malheureusement un inconvénient: le constructeur de A sera appelé deux fois (une fois par B et C) ce qui peut avoir des effets secondaires (surtout si des membres statiques sont utilisés). De plus, si un développeur crée une classe D: public A {} ', la méthode 'init()' peut ne pas être appelée du tout, laissant l'objet dans un état non initialisé. – Marste

0

vous avez besoin de construction de explict appel A comme ceci:

D(int i) : A(i), B(i), C(i) {} 
Questions connexes