2014-04-04 50 views
3

我想學習C++,並編寫了這段代碼。根據我的理解,此代碼需要生成輸出爲"Derived Class",但輸出爲"Base Class"。 請幫我理解這一點。在C++中瞭解繼承

#include <iostream> 
using namespace std; 

class Base { 
    public: 
    char* name; 
    void display() { 
     cout << name << endl; 
    } 

};

class Derived: public Base { 
    public: 
    char* name; 
    void display() { 
     cout << name << ", " << Base::name << endl; 
    } 
}; 

int main() { 
    Derived d; 
    d.name = "Derived Class"; 
    d.Base::name = "Base Class"; 

    Derived* dptr = &d; 

    Base* bptr = dptr; 

    bptr->display(); 
} 

請考慮我作爲一個初學者,並解釋爲什麼它的輸出爲"Base Class"

回答

2

你需要讓display()方法virtual

像這樣:

class Base{ 
    public: 
    char* name; 
    virtual void display() { 
     cout << name << endl; 
} 

virtual允許派生類以'重寫'基類的功能。

+0

@andy ..使其虛擬後,其輸出是「派生類基類」...但我期待只有「派生類」 – someone

+2

@someone:爲什麼不呢?你寫了'cout << name <<「,」<< Base :: name << endl; '不'cout << name << endl' – AndyG

0

http://www.parashift.com/c++-faq/dyn-binding.html

非虛擬成員函數靜態解析。也就是說, 成員函數是基於對象的指針(或引用)的 類型靜態選擇的(在編譯時)。

相反,虛擬成員函數是動態解析的(在 運行時)。也就是說,成員函數是基於對象的類型動態選擇的(在 運行時),而不是指向該對象的指針/引用的類型。

0

如果要通過基類指針調用派生類函數,則需要使基類函數成爲虛函數。將關鍵字虛擬添加到該函數中,並且您的代碼將會很順利。

0

C++ dispatch有點奇怪。除非您聲明顯示方法爲'虛擬',否則bptr->顯示將總是調用基類的顯示。

更詳細的解釋是here

0

多態性(具有指向派生類的實例基類指針一般工作)由指派到虛函數如在其他的答案說明完成。但是,如果您指向具有基類指針的派生類,則將使用基類的數據成員,因爲編譯器不知道派生類的數據成員,並且同樣用於調用基類的函數,所以基類display()函數使用基類name數據成員,您的結果是「基類」。