2013-11-27 183 views
6

根據cppreference非工會類類型沒有任何用戶提供的構造被構造之前將零初始化:值初始化

如果T是一個非工會類類型而不任何用戶提供的構造函數,則該對象初始化爲零,然後隱式聲明的默認構造函數被調用(除非它是微不足道的)

我不知道當C++ 11繼承構造函數應該發生什麼因爲報價中明確提到了默認構造函數爲

考慮下面的例子:

#include <iostream> 

struct A { 
    int a; 
    A() {} 
    A(int i): a(i) {} 
}; 

struct B: public A { 
    using A::A; 
}; 

int main() { 
    B b { 5 }; 
    B* p = new (&b) B{ }; 
    std::cout << b.a << std::endl; 
} 

什麼是正確的輸出,0或5?在值初始化(B{ })之前是否應該只提供繼承構造函數的類類型進行初始化?

回答

6

正確答案是0,因爲B的默認構造函數是隱式聲明的。

請注意,默認情況下,複製&移動構造函數不會被繼承;從§12.9/ 3 [class.inhctor]

引述對於在候選集合比構造不具有參數或具有單一一個複製/移動的構造 其他遺傳構造的每個非模板構造參數,構造函數隱含地聲明爲 ,具有相同的構造函數特性,除非在使用聲明出現或構造函數爲默認值的完整類中存在具有相同 簽名的用戶聲明構造函數,或者複製或移動該類的構造函數。


你舉的例子是一個類似於在N3797上市,§12。9/6(編輯爲簡潔起見)

struct B2 { 
    B2(int = 13, int = 42); 
}; 

struct D2 : B2 { 
    using B2::B2; 
}; 

B2D2候選集遺傳構造的是
- B2(const B2&)
- B2(B2&&)
- B2(int = 13, int = 42)
- B2(int = 13)
- B2()

集目前在D2構造函數是
- D2(),隱式聲明的默認構造函數,而不是繼承
- D2(const D2&),隱式聲明的拷貝構造函數,而不是繼承
- D2(D2&&),隱含宣佈的移動構造函數,而不是繼承
- D2(int, int),隱式聲明的繼承構造
- D2(int),隱式聲明的繼承構造

在你的情況,爲AB候選集繼承構造函數是

A() 
A(int) 
A(const& A) 
A(A&&) 

,並出現在B構造函數是

B() implicitly declared, not inherited 
B(int) implicitly declared, inherited 
B(const& B) implicitly declared, not inherited 
B(B&&) implicitly declared, not inherited 
+0

+1,賓果。粗體通道是關鍵。 – Jon

+0

我認爲將最後一段移到答案的開頭會更清楚。 – Casey