2011-03-23 125 views
8

繼承構造可以說我有什麼我們希望成爲下一個C++標準如下代碼:C++ 0x中

int f(int x) 
{ 
    std::cout << x; 
    return x * x; 
} 

struct A 
{ 
    A(int x) : m_x(x) {} 
    int m_x; 
}; 

struct B : A 
{ 
    using A::A; 
    B() : m_y(f(m_x)) {} 
    int m_y; 
}; 

int main() 
{ 
    B(5); 
} 

這會調用B的默認構造函數,並打印出5,並設置m_y = 25?或者B的默認構造函數沒有運行,並且m_y未初始化?

如果是後者,不調用B默認構造函數的基本原理是什麼?很明顯,A(int)B只繼承初始化A,並使B處於不確定狀態。爲什麼C++會選擇未定義的行爲而不是簡單地調用B()的默認構造函數?它在很大程度上破壞了繼承構造函數的功能。

編輯:

或許這是應該被允許:

using A::A : m_y(...) { std::cout << "constructing..." << std::endl; ...; } 
+1

m_y將初始化,使用A :: A,你會得到像這樣的東西:B :: B(int x):A :: m_x(x){}。或者其他東西:) – hidayat 2011-03-23 10:18:36

+0

C++實際上選擇編譯錯誤代碼,因爲您沒有爲A提供默認構造函數。它不是一個未定義的行爲:) – user396672 2011-03-23 12:43:19

回答

4

using A::A;隱式聲明的派生類B(int)。這就對了。

您的程序的其餘部分不應按預期工作。因爲您正在調用B(int)B(5),並且m_y未被初始化。

請參閱從Bjarne的Stroustrup的網站這個例子:

struct B1 { 
    B1(int) { } 
}; 

struct D1 : B1 { 
    using B1::B1; // implicitly declares D1(int) 
    int x; 
}; 

void test() 
{ 
    D1 d(6); // Oops: d.x is not initialized 
    D1 e;  // error: D1 has no default constructor 
} 

http://www2.research.att.com/~bs/C++0xFAQ.html#inheriting

從相同的鏈接又如:

struct D1 : B1 { 
     using B1::B1; // implicitly declares D1(int) 
     int x{0}; // note: x is initialized 
    }; 

    void test() 
    { 
     D1 d(6); // d.x is zero 
    } 
+0

如果D1有一個默認構造函數,它會在運行時運行「 D1 d(6);「? – Clinton 2011-03-23 10:19:41

+0

他的例子沒有聲明D1的默認構造函數。當然x不會被初始化,不管「使用B1:B1」。然而我的例子聲明瞭一個默認的構造函數。 – Clinton 2011-03-23 10:28:42

+0

@克林頓:是的。但是在你的例子中沒有調用默認的構造函數。因此,無論您是否定義它,都無關緊要,您可以在示例中調用隱式聲明的構造函數,即「B(int)」。 – Nawaz 2011-03-23 10:30:49