2009-06-18 9 views
2

Je cherche une façon propre de faire cela depuis longtemps. Dans mon problème, il existe 3 classes ne partageant aucun parent en commun mais chacune ayant des méthodes avec le même nom (A.doSomething, B.doSomething, C.doSomething). Donc, ayant la même signature de fonction, la classe D héritant de A et utilisant la méthode doSomething() ressemblera à E héritant de B ou C.Hiérarchie d'héritage multiple

Voici un croquis de ce que je voudrais être en mesure de le faire:

class Base { 
    public: 
    void myMethod(void) { doSomething(); } 
}; 

class Independent { 
    public: 
     doSomething(); 
}; 

clase Derived : public Base : public Independent { 
(...) 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
} 

Dans ce problème, objet de type « indépendant » est fourni par une bibliothèque que je ne peux pas changer. Je voudrais définir une classe de base qui utilise des méthodes qui vont être héritées plus tard. Je ne pouvais pas trouver une façon correcte de le faire en utilisant l'héritage virtuel sans provoquer de compilation ambiguë.

+0

Pouvez-vous expliquer votre problème un peu plus clairement? Je vois seulement une méthode appelée "doSomething" dans cet extrait de code, mais vous mentionnez trois classes qui l'ont dans la description, et vous ne faites aucun commentaire sur ce que la méthode "myMethod" est censée être. –

Répondre

5

Vous avez une mauvaise situation là-bas. Une solution à ce serait d'utiliser le motif de modèle Chose curieuse Récurrent pour exécuter l'héritage à la compilation, comme ceci:

template <typename D> 
class Base { 
    public: 
     void myMethod(void) { static_cast<D*>(this)->doSomething(); } 
}; 

class Independent { 
    public: 
     void doSomething(); 
}; 

clase Derived : public Base : public Independent { 
    /*...*/ 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
} 

Sinon, vous pouvez choisir de mettre une classe intermédiaire entre de transmettre à Independent (je suppose vous avez plusieurs classes dérivant des mêmes Base et Independent, et vous ne voulez pas avoir à faire cela pour chaque classe).

template <typename D> 
class Base { 
    private: 
     virtual void doSomethingImpl(); 
    public: 
     void myMethod(void) { doSomethingImpl(); } 
}; 

class Independent { 
    public: 
     void doSomething(); 
}; 

class IndependentWrapper : public Base : public Independent { 
    private: 
     void doSomethingImpl() { Independent::doSomething(); } 
}; 

clase Derived : public IndependentWrapper { 
    /*...*/ 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
}