2013-06-01 47 views
2

我有一個A類和B類。 C類從B類派生並具有A類對象作爲組合。 http://ideone.com/JGT48M構造函數與構圖調用順序

#include "iostream" 
using namespace std; 

class A { 
    int i; 
public: 
    A(int ii) : i(ii) { 
     cout << "\n Constructor of A is called \n"; 

    } 
    ~A() { 
     cout << "\n destructor of A is called \n"; 
    } 
    void f() const {} 
}; 

class B { 
    int i; 
public: 
    B(int ii) : i(ii) { 
     cout << "\n Constructor of B is called \n"; 
    } 
    ~B() { 
     cout << "\n destructor of B is called \n"; 
    } 
    void f() const {} 
}; 

class C : public B { 
    A a; 
public: 
    C(int ii) : a(ii), B(ii) { 
     cout << "\n Constructor of C is called \n"; 
    } 
    ~C() { 
    cout << "\n destructor of C is called \n"; 
    } // Calls ~A() and ~B() 
    void f() const { // Redefinition 
    a.f(); 
    B::f(); 
    } 
}; 

int main() { 
    C c(47); 
} ///:~ 

我已閱讀,構造基於它們是如何在叫我的派生類的構造函數調用。我的意思是,讓有來自REF_BASE1和REF_BASE2衍生然後

REF (int ii) : REF_BASE2(ii), REF_BASE1 (ii) { 

一類稱爲REF意味着REF_BASE2將被稱爲第一則REF_BASE1然後REF構造函數被調用。 如果我們定義它像

REF (int ii) : REF_BASE1(ii), REF_BASE2 (ii) { 

意味着REF_BASE1將被稱爲第一則REF_BASE2然後REF構造函數被調用。

但是,在我上面的程序中,我明確地「錯誤地」指出,通過內部組合變量A先被初始化,然後B被初始化,然而編譯器以正確的方式執行,但未能讓我知道我的錯誤

上述程序,不論順序我在派生類中constcutor初始化列表中指定的輸出

Constructor of B is called 

Constructor of A is called 

Constructor of C is called 

destructor of C is called 

destructor of A is called 

destructor of B is called 

我的問題是 1)爲什麼編譯器不抱怨嗎?還是我正確? 2)是否嚴格遵循派生構造函數中的順序?

+1

編譯器對我發出警告:_「field'a'將在基本'B'後初始化[-Wreorder]」_ – soon

回答

4

我將與第二個問題開始:

2)在派生的構造函數的順序沒有嚴格遵循?

該命令不是出現在您的構造函數初始化列表中的,而是出現在您的類定義中的基類。

所以,如果你的類定義是這樣的:

struct A : B, C 
{ 
    // ... 
}; 

隨後的B構造將是C構造函數之前,你在A的構造函數初始化列表中指定什麼樣的順序調用,不管。

第12.6.2/C++的11標準規定的10:

在非委託構造函數,以下列順序進行初始化:

- 首先,並只爲(1.8)的構造函數,虛擬基類在 中初始化,它們出現在基類的有向無環圖的深度優先從左到右的遍歷中, 其中「從左到右」是派生類base-specifier-list中基類的出現順序。

- 然後,直接基類中聲明的順序,因爲它們出現在基本說明符列表 (不管MEM-初始化的順序的)初始化。

- 然後,按照靜態數據成員在類定義 (不管mem初始化器的順序)中聲明的順序對其進行初始化。

- 最後,執行構造函數體的複合語句。

現在第一個問題:

1)爲什麼編譯器不抱怨嗎?

編譯器可以提醒你,在構造函數初始化列表中初始化順序是從一個基類列表(GCC確實有-Wall)不同,但並不一定。最終,只有後者很重要。

+0

@MAG:這是否回答您的問題? –