2017-03-27 1 views
2

Est-ce que le design suivant est valide en C++?Classe d'abtraction dérivée d'une classe nominale. Est-ce valable?

#include <iostream> 
#include <memory> 

using namespace std; 

struct Base { 
    virtual void SomeMethod() { 
     std::cout<<"Do Something"<<std::endl; 
    } 
}; 

struct Der : public Base { 
    virtual void SomeMethod() override = 0; 
}; 

struct DerDer : Der { 
    virtual void SomeMethod() override 
    { 
     std::cout<<"Do something derived."<<std::endl; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    auto x = std::unique_ptr<Base>(new DerDer); 
    x->SomeMethod(); 
    return 0; 
} 

Fonctionne sur g ++ 6.2.

Je dérive d'une classe normale, en convertissant cette méthode en abstraction, puis en la remplaçant après avoir dérivé à nouveau.

Est-ce correct en C++ de dériver d'une classe, puis de retourner une méthode implémentée à l'abstrait?

La raison pour laquelle je dois faire ceci, c'est que dans un grand programme, auquel j'ajoute des fonctionnalités, j'essaye de avoid a diamond model. Pour ce faire, je prévois de mettre toutes les méthodes courantes dans la classe Der, et en faire tout hériter, sans jouer avec la classe Base.

+0

'Der :: SomeMethod' devrait aussi être' override'. Vous devriez appeler la méthode via un 'Base *': http://ideone.com/QJ5su3 – mch

+0

@mch Mieux? :) ... –

Répondre

1

C'est légal.

Mais si vous voulez éviter le modèle Diamon, il y a another workarounds

+0

Les réponses à la question liée montrent comment créer une hiérarchie en forme de losange. Pas comment l'éviter. – user2079303

+0

@ user2079303 J'allais le dire. Tu m'as battu! –

+0

Euh, je pense que la bonne phrase est: "éviter les problèmes du modèle diamon" :) – amchacon

-1

Techniquement il n'y aurait pas de problème mais ce n'est jamais un bon design lorsque vous héritez d'une interface (ou classe abstraite) d'une classe concrète.

Si vous souhaitez fournir des fonctionnalités communes dans Der, vous pouvez utiliser la composition. Parce que votre classe Der serait comme une classe d'utilité. Ne faites pas classe der comme classe abstraite.

Class DerDer : class base 
{ 
    private der ptrUtilityObj; 
} 

À l'avenir, peut-être un nouveau développeur confondra qu'il devrait mettre en place de nouvelles fonctionnalités dans la classe de base ou de la classe Der.