2017-07-21 5 views
0

J'ai deux classes de base et une classe qui hérite des deux classes de base. Les deux classes de base ont une fonction virtuelle avec la même signature, et je souhaite fournir différentes implémentations dans la classe dérivée à chaque fonction virtuelle.Comment choisir la classe de base lors de la substitution d'une fonction en C++?

class A{ 
    virtual void f() = 0; 
} 
class B{ 
    virtual void f() = 0; 
} 
class Derived:public A, public B{ 
    void A::f() override{ // Error 
     ... 
    } 
    void B::f() override{ // Error 
     ... 
    } 
} 

Quelle est la bonne façon de procéder? (Je ne peux pas renommer la fonction virtuelle. En fait, les deux classes de base sont générées à partir de la même classe de modèle.)

+1

Qu'est-ce que vous essayez de faire ...? Que serait la sémantique de 'derived-> f()'? –

+0

La classe dérivée hérite des mêmes classes de modèle de mixage avec des arguments différents. La fonction f() est en fait une fonction comme update(), et j'ai besoin de définir différentes fonctions de mise à jour pour différents arguments. – eivour

+0

Veuillez écrire un code qui représente honnêtement votre cas d'utilisation réel. Il n'y a aucun moyen de faire la compilation ci-dessus ni aucune sémantique significative. –

Répondre

1
template <typename T> 
class AShim : public A { 
    void f() override { 
    static_cast<T*>(this)->A_f(); 
    } 
}; 

template <typename T> 
class BShim : public B { 
    void f() override { 
    static_cast<T*>(this)->B_f(); 
    } 
}; 

class Derived: public AShim<Derived>, public BShim<Derived> { 
    void A_f(); 
    void B_f(); 
}; 
+0

C'est comme un OOP à l'envers. Avoir une classe abstraite avec deux implémentations différentes semble être un moyen plus direct d'obtenir le même effet. –

1
class A { 
public: 
    virtual void f() = 0; 
}; 
class B { 
public: 
    virtual void f() = 0; 
}; 
class Derived :public A, public B { 
public: 
    void A::f() { 
     cout << "Inside A's version"<<endl; 
    } 
    void B::f() { 
     cout << "Inside B's version"<<endl; 
    } 
}; 

int main() 
{ 
    Derived derived; 
    cout << "calling A" << endl; 
    A *a; 
    a = &derived; 
    a->f(); 
    cout << "calling B" << endl; 
    B *b; 
    b = &derived; 
    b->f(); 
} 

fonctionne bien pour moi. Pas besoin de mentionner explicitement le mot-clé override puisque les fonctions virtuelles pures seront remplacées grâce à ses propriétés par défaut. Utilisez la portée de la classe de base tout en définissant les fonctions comme vous l'avez déjà fait. Utilisez public spécificateur d'accès pour permettre aux classes dérivées de remplacer la fonction virtuelle pure. C'est tout.

+0

On dirait que votre compilateur est [non conforme] (https://stackoverflow.com/a/7112168/703016). Est-ce MSVC? –

+0

@BaguetteGarlique Je confirme, cela fonctionne dans MSVC. Toujours pas sûr si c'est conforme :) –

+0

Oui c'est de MSVC –