[英]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.