簡體   English   中英

為什么用戶提供的默認構造函數會導致未初始化的成員?

[英]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 = {}; 不能進行聚合初始化,而是調用默認構造函數。 默認構造函數(在AB )沒有為成員指定初始值設定項,因此該成員是default-initialized ,對於基本類型,例如int ,這意味着它不會被設置為任何值。 它的價值將保持不確定

訪問您的程序所做的不確定值會導致未定義的行為


如果您自己聲明一個構造函數,則該構造函數有責任適當地初始化所有成員。 該規則= {}{}永遠只有初始化假設用戶提供的默認構造函數,如果存在的話,的確,它提供了合理的初始化其所有成員的感覺是正確的下舉行,它並沒有意味着必然的零初始化

struct B有一個用戶提供的構造函數,因此它沒有獲得可以將成員初始化為零的默認構造函數。 您的用戶提供的構造函數取代了它,因此您必須自己完成這項工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM