2009-01-07 9 views
43

Quelle est la signification de l'héritage "virtuel"?héritage virtuel

j'ai vu le code suivant, et ne comprenaient pas la signification du mot-clé virtual dans le contexte suivant:

class A {}; 
class B : public virtual A; 
+1

Avoir un [lire cette] (http://stackoverflow.com/questions/21558/in-c-virtual-base-class#21607) (il a été demandé avant). –

Répondre

38

L'héritage virtuel est utilisé pour résoudre le problème DDD (Dreadful diamant sur Dérivation).

Regardez l'exemple suivant, où vous avez deux classes qui héritent de la même classe de base:

class Base 
{ 

public: 

virtual void Ambig(); 

}; 

class C : public Base 
{ 

public: 

//... 

}; 

class D : public Base 
{ 
public: 

    //... 

}; 

Maintenant, vous voulez créer une nouvelle classe qui hérite à la fois des classes C et D (qui ont tous deux hérité de la fonction Base :: Ambig()):

class Wrong : public C, public D 
{ 

public: 

... 

}; 

Pendant que vous définissez la classe « Faux » ci-dessus, vous avez réellement créé le (problème de diamant Dérivation) DDD, parce que vous ne pouvez pas appeler:

Wrong wrong; 
wrong.Ambig(); 

Ceci est une fonction ambiguë, car elle est définie deux fois:

Wrong::C::Base::Ambig() 

Et:

Wrong::D::Base::Ambig() 

afin d'éviter ce genre de problème, vous devez utiliser l'héritage virtuel, qui saura se référer à la ri Fonction Ambig().

donc - définir:

class C : public virtual Base 

class D : public virtual Base 

class Right : public C, public D 
+10

'Wrong' pourrait très bien être' Correct'. Ça dépend de la situation. Les MI normaux et les MI virtuels ont tous les deux leur place, même en présence de motifs de diamant (pas terrible). Rappelez-vous juste qu'il n'y a pas de taille qui convient à tous. –

+3

Je pense que vous attirez l'attention sur la mauvaise chose - avec vos classes "Wrong" et "Right". Ils sont identiques pour une raison - ils ne sont pas le problème. Bien que vous ayez correctement l'héritage virtuel pour les parents C et D, vous avez tendance à les ignorer - C et D étaient ceux qui étaient "faux" et qui ont besoin d'être corrigés, pas la classe dérivant des deux. – Kevin