2017-07-16 94 views
0

在運行下面的代碼,爲何是基類的構造函數導出的第一即使我們首先聲明派生類的對象。爲什麼基類的構造函數首先調用?

#include<iostream> 

using namespace std; 

class base { 
    public: 
    base() 
    { cout<<"Constructing base \n"; } 
    ~base() 
    { cout<<"Destructing base \n"; } 
}; 

class derived: public base { 
    public: 
    derived() 
    { cout<<"Constructing derived \n"; } 
    ~derived() 
    { cout<<"Destructing derived \n"; } 
}; 

int main(void) 
{ 
    derived *d = new derived(); //d is defined ahead of the base class object 
    base *b = d; 
    delete b; 

    return 0; 
} 
+0

你還會期待什麼?爲什麼? – user0042

+2

提示:在'derived'裏面有一個'base' **子對象**。 – StoryTeller

+0

問題不清楚。你可以解釋嗎? – MoraRockey

回答

4

繼承的表示「是」的關係,讓derived類的所有對象都是base類的對象。 derived對象都認爲base對象做數據和方法,再加上數據和方法在derived類聲明明確宣佈。

根據類的實現編寫Derived類是完全可能的(也是常見的)。例如,假設我們有

class Base { 
public: 
    Base() { n = 5; } 
    int GetN() const { return n; } 
private: 
    int n; 
}; 

class Derived : public Base { 
public: 
    Derived() { m = GetN() * 2; } 
    int GetM() const { return m; } 
private: 
    int m; 
}; 

現在我們所期待

Derived* d = new Derived(); 
std::cout << d->GetM() << std::endl; 

打印10,這是它應該做的(除非我的一部分的任何錯誤)到底是什麼。這是一個完全合理的(如果有點做作)的事情。

語言可以得到這樣的代碼能夠正常工作的唯一途徑是構建Derived類型的對象的時候,Derived構造函數之前運行Base構造。這是因爲Derived構造函數依賴於能夠調用GetN()方法,它繼承自Base,其正確功能取決於數據成員n已在Base構造函數中正確初始化。

總之,構造任何Derived對象時,C++必須首先構造它爲Base對象,因爲Derived是-一個Base和通常將取決於它的實現和數據。

當你

base* b = d; 
在你的代碼

,你聲明一個變量b是類型的「指針base對象」,然後初始化與d持有相同的內存地址此變量。編譯器不介意你這樣做,因爲所有derived對象是base對象,所以它使您可能要正確對待db感。這裏的對象實際上並沒有發生什麼,它只是一個指針變量的聲明和實例化。對象指向d已經是一個base對象,因爲所有derived對象是基本對象。

注意,此解釋是故意有點模糊圓的邊緣和是遠不在C++基類和派生類之間的關係的完整說明。你會想看看其他文章/書籍/標準。我希望這對初學者來說是相對容易理解的。

相關問題