簡體   English   中英

C ++ 11中默認初始化的含義已更改?

[英]Meaning of default initialization changed in C++11?

C ++ 2003 8.5 / 5說:

默認初始化類型T的對象意味着:

—如果T是非POD類類型(第9節),則調用T的默認構造函數(如果T沒有可訪問的默認構造函數,則初始化格式不正確);

—如果T是數組類型,則每個元素都將默認初始化;

—否則,將對象初始化為零

[重點已添加。]

C ++ 2011標准將最后一項更改為

—否則, 不執行初始化

對於某些程序來說,這似乎是一個重大突破。 這是故意的嗎?

編輯

這是一些激發這個問題的代碼:

class Foo {
  public:
    Foo() : m_values() {}

    int m_values[3];
};

在C ++ 11之前,我認為在默認構造函數中明確提及m_values默認初始化該數組。 並且由於數組的元素是標量的,所以我希望這意味着所有值都設置為0。

在C ++ 11中,似乎不再保證會發生這種情況。 但是也許,正如Mooing Duck在評論中指出的那樣,也許這不再是默認初始化的情況,而是某種保留了預期行為的其他形式。 歡迎引用。

最終效果幾乎相同。 在C ++ 03中, 默認初始化的使用僅限於非POD類類型,因此最后一點從未應用。 在C ++ 11中,該標准通過消除有關使用默認初始化的條件來簡化措辭,並更改了默認初始化的定義以涵蓋所有情況,以對應以前發生的情況。

根據cppreference.com (因為它使用的語言比標准語言更友好):

默認初始化在以下三種情況下執行:

3)當構造函數初始化列表中未提及基類或非靜態數據成員時,將調用該構造函數。

在以下三種情況下執行值初始化:

3,7)當使用帶有一對空括號or braces (since C++11)的成員初始化器初始化非靜態數據成員或基類時or braces (since C++11)

請注意,C ++ 11部分屬於or braces ,而不屬於整個段落。

和:

值初始化類型T的對象意味着:
—如果T是數組類型,則每個元素都進行值初始化;
—否則,該對象將被零初始化

因此,在C ++ 11中, 默認初始化不會對成員進行零初始化,而對值進行初始化

嚴格來說, default-initialize的定義已從C ++ 03更改為C ++ 11。 但是,還必須考慮到_default-initialize_d對象的情況已更改:

§8.5p9C ++ 03指出:

如果沒有為一個對象指定初始化程序,並且該對象是(可能是cv限定的)非POD類類型(或其數組),則該對象應被默認初始化;否則,默認為初始化。 如果對象是const限定類型,則基礎類類型應具有用戶聲明的默認構造函數。 否則,如果未為非靜態對象指定初始化程序,則該對象及其子對象(如果有)具有不確定的初始值;否則,為false。 如果對象或其子對象為const限定類型,則程序格式錯誤。

§8.5p11C ++ 11指出:

如果未為對象指定初始化程序,則該對象為默認初始化;否則,默認為初始化。 如果未執行初始化,則具有自動或動態存儲持續時間的對象的值不確定。

正如@JamesKanze指出的那樣,當未為非POD類類型的對象指定初始化器時,將在C ++ 03中執行默認初始化 在C ++ 11中,如果未指定初始化程序,則將默認初始化對象(任意類型)。 由於此更改,還必須更改default-initialize的定義,以便與C ++ 03兼容。


您的示例與default-initialization沒有關系。 通常情況下,將其初始化程序為一組空括號的對象進行值初始化

暫無
暫無

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

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