2011-04-09 109 views
2

在繼承中,當派生類被實例化(派生類obj被創建)時,第一個內存被擱置。在此之後,派生類構造函數被調用。繼承 - 實例化問題

class Base 
    { 
    public: 
     int m; 
     Base(int x=0) 
      : m(x) 
     { 
     } 
    }; 

    class Derived: public Base 
    { 
    public: 
     double n; 

      Derived(double y=0.0) 
      : n(y) 
      { 
     } 
    }; 

在上面的例子中,當創建派生類對象時,調用派生類的構造函數。

問題是,從我所研究的基類構造函數在調用派生類構造函數之前調用。但是,派生類中的任何地方都沒有明確的指令來首先轉到基類構造函數。編譯器如何知道基類構造函數必須先被執行?

我想答案應該是這條線在基類中聲明:

class Derived: public Base 

但是,問題是通過改變派生類,如下所示,我們可以確保基類構造函數被調用之前初始化派生構造函數體執行。

class Derived: public Base 
    { 
    public: 
     double n; 

      Derived(double y=0.0, int z=0) 
      : Base(z), n(y) 
      { 
     } 
    }; 

所以,問題是,在第一個例子中,沒有聲明,告訴基類構造函數首先被調用,但它實際上是第一次調用,在第二改變的例子,我告訴編譯器將跳轉首先是基類構造函數。難道它不知道首先轉到基類構造函數?這兩個例子之間執行的區別是什麼?步驟是什麼?

Regards,

回答

0

在第一個示例中,您調用默認構造函數。在第二個例子中,你調用構造函數parametar

+0

在第二個示例中,編譯器不會調用基類構造函數,並在它看到調用之前對其進行了初始化在派生類的構造函數?? – Krishna 2011-04-09 17:52:48

+0

在這兩個例子中基礎構造函數被稱爲第一個 – 2011-04-09 17:57:39

0

是什麼在兩個例子之間執行的差異,哪些步驟?

不同的是,在第一種情況下默認的構造函數將被調用,而在第二種情況下,你已經選擇之一。

+0

但是不是基類構造函數調用BEFORE派生類構造函數被調用?因此,編譯器看到這一行:「Derived(double y = 0.0,int z = 0) :Base(z),n(y)」它應該在之前已經調用基類構造函數。 – Krishna 2011-04-09 17:56:00

+0

@Krisshna,在第二種情況下,你顯式強制編譯器調用正確的構造函數。而已。 – UmmaGumma 2011-04-09 18:05:30

1

如果你有一個球,你從它派生出一個RedBall,然後創建一個RedBall,你需要的第一件事就是一個球,然後你可以把它畫成紅色。

因此,要在您的示例中創建Derived類型的對象,您需要先從Base類型的對象開始,然後從中構造Derived。所以即使你沒有明確地調用基類的構造函數,編譯器也知道必須這樣做。該行

class Derived: public Base 

實際上是通知編譯器這一點的指令。

在第二種情況下,你正在明確它。這可以用在你想調用poarameters所說的基類的構造函數的情況下。

3

編譯器知道要調用基類的構造函數,因爲你已經指定了要通過的聲明傳承基地:

class Derived : public Base

不管是什麼,編譯器會實例化(即調用構造函數)之前調用Derived的構造函數。它也是爲了正確構造派生類。

在第二個示例中,您在初始化列表中聲明:Base(z),您告訴編譯器使用此構造函數顯式調用/初始化Base類。如果不通過初始化列表指定構造函數,編譯器將始終調用默認的構造函數。在初始化列表中指定正確的構造函數(即使它是默認值)被認爲是最佳實踐。

0

我認爲誤解是C++語言是以某種方式分步解釋的,否則我無法解釋「編譯器是否不會調用基類構造函數,並在它看到調用之前初始化它派生類構造函數「。

實際情況並非如此,編譯器在開始生成輸出之前「看到」所有編譯單元。如果它看到你已經明確地調用了一個特定的構造函數 - 在你的情況下通過Base(z)它會在創建Derived對象時調用該構造函數。否則,它將調用Base的默認構造函數。

最好不要聲明你的基構造器爲Base(int x = 0)。嘗試創建一個無參數的構造函數和Base(int),並在每個中放置一個斷點,以確切地看到哪一個被調用。 (或者,在Base(int x = 0)中放置一個斷點並檢查x的值)

+0

感謝您的回答!這就是我一直在尋找的!我以爲編譯器會逐行解釋程序! – Krishna 2011-04-09 20:18:50