2012-01-08 3 views
6

La situation est la suivante.Empêcher la classe inheritor de surcharger la fonction virtuelle de la classe de base

class Interface 
{ 
public: 
    virtual void foo() = 0; 
} 

class MyClass : Interface 
{ 
public: 
    virtual void bar() = 0; 
private: 
    void foo() 
    { 
     //Some private work and checks. 
     bar(); 
    }; 
} 

Je veux que mon utilisateur va créer une classe qui hérite de MyClass, et ils devront mettre en œuvre il bar(). Mais comment puis-je enfoce qu'ils ne remplacent pas foo()? parce que c'est important pour moi d'utiliser mon foo().

+0

Est-ce que cela compile? Si c'est le cas, vous n'avez pas de problème, puisque votre foo est privé. Edit: ah, non, il ne compile pas ... –

+2

@MrLister: Les méthodes privées peuvent encore être remplacées. –

+0

Vrai, désolé. Pas de soucis alors. La réponse a déjà été donnée. –

Répondre

13

En C++ 11 vous pouvez marquer la méthode comme final pour l'empêcher d'être overriden:

class MyClass : Interface 
{ 
public: 
    virtual void bar() = 0; 
private: 
    void foo() final 
    { 
     //Some private work and checks. 
     bar(); 
    }; 
} 
+0

Merci, vous m'amenez dans la bonne direction. mais en C++ 11V1.0 'final' a été changé en' sealed'. –

+5

Lire [cette question] (http://stackoverflow.com/questions/7026462). 'sealed' est spécifique à microsoft. 'final' est défini au §7.6.4 [dcl.attr.final] de la norme C++ 11. –

+0

Merci! C'est ce que je cherche: D – mr5

6

Comme par autre réponse, vous pouvez utiliser final mot-clé dans 11 (telle installation est similaire C de au mot-clé final de Java).

Pour le code C++ 03, vous pouvez utiliser le mécanisme CRTP (fourni si vous pouvez modifier la définition de Interface)

template<typename Derived> 
class Interface 
{ 
public: 
    void foo() // not 'virtual' 
    { 
    static_cast<Derived*>(this)->foo(); 
    } 
} 

class MyClass : public Interface<MyClass> 
{ 
public: 
    virtual void bar() = 0; 
private: 
    void foo() 
    { 
     //Some private work and checks. 
     bar(); 
    }; 
} 

Alors maintenant, vous avez enlever la ness virtual du foo() et la liaison qui va se passer au moment de la compilation. Rappelez-vous que CRTP est livré avec ses propres limites, donc vous pouvez l'utiliser ou non.

Questions connexes