2012-02-28 92 views
13
class Base 
{ 
    public: 
    virtual void func() const 
    { 
    cout<<"This is constant base "<<endl; 
    } 
}; 

class Derived : public Base 
{ 
    public: 
    virtual void func() 
    { 
    cout<<"This is non constant derived "<<endl; 
    } 
}; 


int main() 
{ 
    Base *d = new Derived(); 
    d->func(); 
    delete d; 

    return 0; 
} 

爲什麼輸出打印出「這是恆定基數」。然而,如果我刪除基礎版本的func()中的const,它會打印出「This is non constant derived derived」虛擬功能常量vs虛擬功能非常量

d-> func()應該調用Derived版本,即使基礎func ?

+0

可能的重複http://stackoverflow.com/questions/7504300,http://stackoverflow.com/questions/3827374和http://stackoverflow.com/questions/4152799。 – 2012-02-28 19:12:54

+0

[虛函數是在基類中的常量,而不是在派生的常量]的可能重複(http://stackoverflow.com/questions/7504300/virtual-function-that-is-const-in-the-base- class-and-not-const-in-the-derived) – 2012-02-28 19:58:16

回答

28
virtual void func() const //in Base 
virtual void func()  //in Derived 

const部分是函數簽名,這意味着派生類定義了一個新函數,而不是重寫基類功能的實際的一部分。這是因爲他們的簽名不匹配。

當您刪除const一部分,那麼他們的簽名相匹配,然後編譯器看到的基類功能funcfunc重寫版本,因此派生類的功能是,如果運行時類型的稱爲派生類中定義對象是Derived類型。這種行爲稱爲運行時多態。

+0

我很困惑這裏。如果兩者都被視爲2個不同的函數,爲什麼d-> func()調用派生版本,因爲這裏沒有適用的const。 – vamsi 2012-02-28 19:15:30

+1

對。事實上,一個類通常定義兩個相同的函數,一個是「const」,另一個不是。 – 2012-02-28 19:16:36

+2

@vamsi,'Base'的定義只包含一個函數,所以這就是所謂的函數。 – 2012-02-28 19:17:49

3

不,因爲virtual void func()不是virtual void func() const的覆蓋。

4

virtual void func()實際上是與virtual void func() const不同的簽名。因此,您並未覆蓋原始的只讀基本函數。您最終在Derived中創建了一個新的虛擬函數。

如果您嘗試創建指向成員函數(PTMF)的指針,您也可以瞭解更多信息,但這是非常罕見的必要條件(可能對研究或實踐有好處)。

C++ 11中的override關鍵字特別方便,可以幫助避免這些類型的錯誤。然後編譯器會告訴你,你在派生的'func'定義不會覆蓋任何東西。