2012-01-08 65 views
6

情況就是這樣。防止繼承者類重寫基類的虛函數

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

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

我想,我的用戶將創建從MyClass的繼承一個類,他們將不得不實施有bar()
但我怎麼能enfoce他們不會覆蓋foo()?因爲使用我的foo()對我很重要。

+0

這是否編譯?如果是這樣,你沒有問題,因爲你的foo是私人的。編輯:啊,不,它不編譯... – 2012-01-08 11:49:44

+2

@MrLister:私有方法仍然可以被重寫。 – 2012-01-08 11:51:08

+0

真的,對不起。沒關係。答案已經給出。 – 2012-01-08 12:00:52

回答

13

在C++ 11可以標記該方法final以防止它被重寫:

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

謝謝,你讓我走向正確的方向。但在C++ 11V1.0中,「final」被改爲「sealed」。 – 2012-01-08 12:02:02

+5

閱讀[這個問題](http://stackoverflow.com/questions/7026462)。 'sealed'是微軟特有的。 'final'在C++ 11標準的§7.6.4[dcl.attr.final]中定義。 – 2012-01-08 20:13:53

+0

謝謝!這是我正在尋找的:D – mr5 2014-02-24 06:44:00

6

按照對方的回答,您可以在C++ 11(例如設施使用final關鍵字是類似到Java的final關鍵字)。

對於C++代碼03,你可以使用CRTP機制(提供,如果你可以改變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(); 
    }; 
} 

所以,現在你必須刪除virtual內斯的foo()和結合會發生在編譯時。請記住,CRTP有其自身的限制,因此是否使用它取決於您。