![](/img/trans.png)
[英]A defaulted default constructor, why is it not a user-provided default constructor?
[英]Why does a user-provided default constructor lead to an uninitialized member?
請考慮以下代碼:
#include <iostream>
struct A{ // with implicit default constructor
int number;
};
struct B{
int number;
B(){}; // user-provided default constructor
};
int main()
{
A aa = {};
B bb = {};
std::cout << "aa.number: " << aa.number << std::endl;
std::cout << "bb.number: " << bb.number << std::endl;
}
在線運行代碼會產生以下輸出:
aa.number: 0
bb.number: 19715
為什么 bb.number 未初始化? 我認為使用 ={} 可以保證零初始化?
我認為使用 ={} 可以保證零初始化?
只有當類型是“正確的”時才是正確的,而B
不是。 B bb = {};
將默認構造一個B
和你的默認構造函數B(){};
, 不初始化number
所以無論如何, number
永遠不會被初始化,因為這是你的默認構造函數的工作方式。 如果你有一個“正確”的構造函數,比如
B() : number(0) {};
// or use
int number = 0;
B(){};
然后,當默認構造時,您將獲得number
零初始化。
這不是A
的情況,因為A
是一個聚合,並且如果使用空的支撐初始化列表( {}
技術名稱{}
,則它們具有某些保證,例如零初始化。
A
是聚合類型,因為它沒有任何用戶提供的構造函數(並滿足一些其他要求)。
因此A aa = {};
不叫隱式生成的默認構造函數。 相反,使用花括號括起來的初始化列表進行初始化執行聚合初始化,這對於空列表意味着成員被初始化為好像由{}
初始化程序,這反過來意味着對於標量類型的成員,例如int
,它將被初始化為零。
B
不是聚合類型,因為它確實具有用戶提供的構造函數。
因此B bb = {};
不能進行聚合初始化,而是調用默認構造函數。 默認構造函數(在A
或B
)沒有為成員指定初始值設定項,因此該成員是default-initialized ,對於基本類型,例如int
,這意味着它不會被設置為任何值。 它的價值將保持不確定。
訪問您的程序所做的不確定值會導致未定義的行為。
如果您自己聲明一個構造函數,則該構造函數有責任適當地初始化所有成員。 該規則= {}
或{}
永遠只有初始化假設用戶提供的默認構造函數,如果存在的話,的確,它提供了合理的初始化其所有成員的感覺是正確的下舉行,它並沒有意味着必然的零初始化。
struct B
有一個用戶提供的構造函數,因此它沒有獲得可以將成員初始化為零的默認構造函數。 您的用戶提供的構造函數取代了它,因此您必須自己完成這項工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.