2010-12-16 36 views
10

如何強制基類方法不被派生類覆蓋?如何防止在派生類中重寫方法?

+5

不要它在基類中是虛擬的?然後它不能被覆蓋,只有重載。如果這是個問題,那麼就沒有直接相當於Java的「最終」方法。 – 2010-12-16 21:51:08

+0

因此,如果不使用虛擬關鍵字,我們無法制作它,那麼它們是如何在JAVA中執行的,然後在Java中執行 – sriks 2010-12-17 13:15:42

+0

,標記了一個'final'方法禁止實現該方法的子類,並且編譯器和/或字節碼驗證程序將強制執行此操作。在C++中,沒有辦法禁止它,只是通過定義「覆蓋」,只有虛擬函數才能被「覆蓋」。 – 2010-12-17 14:33:37

回答

14

如果您使方法非虛擬,派生類不能重寫該方法。然而,一個類不能從一個基類中覆蓋一個方法,並且也會阻止其他派生類覆蓋相同的方法。一旦該方法是虛擬的,它就保持虛擬。

+1

+1:然而,這個部分對我來說非常重要。 – imallett 2013-05-26 21:37:43

+4

使用C++ 11,您可以使用final說明符來避免在派生類中覆蓋方法 – tharinduwijewardane 2016-02-10 07:43:32

1

好吧,如果你想保持公開,不要聲明它是虛擬的。

編輯:Srikanth評論想知道重寫派生類中的私有成員函數。

class A 
{ 
public: 
    virtual ~A(){}; 
    void test() 
    { 
     foo(); 
    }; 
private: 
    virtual void foo() 
    { 
     std::cout << "A"; 
    }; 
}; 


class B : public A 
{ 
public: 
    virtual void foo() 
    { 
     std::cout << "B"; 
    }; 
}; 


void test() 
{ 
    B b; 
    A& a = b; 

    a.test(); // this calls the derived B::foo() 

    return 0; 
}` 
+3

派生類仍然可以覆蓋虛擬專用成員函數。 – 2010-12-16 22:01:49

+0

我已編輯,thanx爲更正。 – 2010-12-16 22:21:18

+0

但我們如何重寫一個私人方法,而不使派生的朋友或減少訪問說明 – sriks 2010-12-18 23:28:43

2

不要讓它變成虛擬的。

這不會阻止派生自你的類並隱藏該函數(通過提供另一個成員函數具有相同的名稱)。然而,如果你的類不是被派生出來的(沒有虛擬析構函數,沒有虛擬成員函數),那應該不是問題。

-1

簡短的回答:沒有必要這樣做。很長的答案,你可以做some twists,但它值得嗎?

18

如果您能夠使用C++ 11中的final說明符,則可以防止派生類重寫該方法。 (Microsoft編譯器似乎支持類似sealed類似的語義。)

下面是一個例子:

#include <iostream> 

struct base { 
    // To derived class' developers: Thou shalt not override this method 
    virtual void work() final { 
     pre_work(); 
     do_work(); 
     post_work(); 
    } 
    virtual void pre_work() {}; 
    virtual void do_work() = 0; 
    virtual void post_work() {}; 
}; 

struct derived : public base { 
    // this should trigger an error: 
    void work() { 
     std::cout << "doing derived work\n"; 
    } 
    void do_work() { 
     std::cout << "doing something really very important\n"; 
    } 
}; 

int main() { 
    derived d; 
    d.work(); 
    base& b = d; 
    b.work(); 
} 

這裏就是我得到的,當我嘗試編譯:

$ g++ test.cc -std=c++11 
test.cc:17:14: error: virtual function ‘virtual void derived::work()’ 
test.cc:5:22: error: overriding final function ‘virtual void base::work()’ 
+0

問題:爲什麼我不希望在派生類中重寫「work()」爲「虛擬」?爲什麼不把它標記爲final? – Sonic78 2017-12-11 09:13:20

+0

@ Sonic78好問題!在真實世界的代碼中,你可能有另一個基類來「base」,它提供了一個虛擬函數,你想阻止它在源自中間基類的類中被覆蓋。 – moooeeeep 2017-12-12 07:55:45

相關問題