2010-05-08 7 views
6

Le scénario générant ceci étant assez complexe, je vais enlever quelques morceaux et donner une représentation précise des classes impliquées.C++ Héritage multiple Question

/* This is inherited using SI by many classes, as normal */ 
class IBase 
{ 
virtual string toString()=0; 
}; 

/* Base2 can't inherit IBase due to other methods on IBase which aren't appropriate */ 
class Base2 
{ 
string toString() 
{ 
    ... 
} 
}; 

/* a special class, is this valid? */ 
class Class1 : public IBase, public Base2 
{ 
}; 

Alors, est-ce valable? Y aura-t-il des conflits sur toString? Ou Class1 peut-il utiliser Base2 :: toString pour satisfaire IBase? Comme je l'ai dit, il y a beaucoup d'autres choses qui ne sont pas montrées, donc les suggestions pour des changements de conception majeurs sur cet exemple ne sont probablement pas utiles ... bien que toutes les suggestions/conseils généraux soient les bienvenus.

Mon autre pensée était quelque chose comme ceci:

class Class1 : public IBase, public Base2 
{ 
virtual string toString() 
{ 
    return Base2::toString(); 
} 
}; 

Cela construit et des liens, mais je n'ai aucune idée si elle a des bugs cachés.

Répondre

2

Vous pouvez résoudre ce problème en utilisant "l'héritage virtuel".

envisager de créer une classe de base commune qui seulement définit une méthode toString virtuelle pure (ou, en réalité, la version virtuelle pure de toutes les méthodes, il est logique pour les deux IBase et Base2 d'avoir), par exemple

class Stringable { 
    public: 
    virtual string toString() = 0; 
}; 

Ensuite, ont tous les deux IBase et Base2 Hériter de cette classe Stringable:

class IBase : public Stringable 
{ 
}; 

class Base2 : public Stringable 
{ 
public: 
    virtual string toString() 
    { ... } 
}; 

Maintenant qu'il en est encore ne fonctionnera pas parce que Class1 aura hérité deux copies de la base Stringable class, dont une seule a une implémentation pour toString dans sa hiérarchie d'héritage. Ceci est connu comme le "dreaded diamond". Toutefois, si IBase et Base2 devaient hériter pratiquement de Stringable, comme ceci:

class IBase : virtual public Stringable 
{ 
}; 

class Base2 : virtual public Stringable 
{ 
public: 
    virtual string toString() 
    { ... } 
}; 

Ensuite, cela indique au compilateur qu'il ne devrait y avoir une classe de base Stringable commune même si IBase et Base2 sont tous deux hérités par un classe, ce qui est exactement ce que vous voulez, parce que le Base2::toString est utilisé pour Class1.

Votre deuxième idée n'a pas de «bugs cachés», mais est un peu difficile à implémenter à plusieurs reprises, comme vous vous en rendez probablement compte.

1

Cela devrait fonctionner correctement.

Vous remplacez correctement l'interface IBase pour fournir une définition de ToString() qui sera envoyée à Base2::ToString().

Notez que Base2 ne déclare pas toString() comme virtuel, donc Class1 ne peut pas remplacer le comportement de Base2::ToString. Aucune ambiguïté là-bas. Et, en outre, ce n'est pas le problème de diamant classique dans l'héritage multiple résolu par virtual inheritance parce qu'ils ne partagent pas une classe de base.