簡體   English   中英

C++ 中的聚合初始化安全

[英]Aggregate Initialization Safety in C++

假設我有以下結構:

struct sampleData
{
       int x;
       int y;
};

並且在使用時,我想將sampleData類型的變量初始化為已知的 state。

sampleData sample = { 1, 2 } 

后來,我決定需要將其他數據存儲在我的sampleData結構中,如下所示:

struct sampleData
{
       int x;
       int y;
       int z;
};

據我了解,從我的 pre- z數據結構中遺留下來的兩個字段初始化仍然是一個有效的語句,並且將被編譯,用默認值填充缺失的字段。

這種理解正確嗎? 我最近一直在 Ada 工作,它也允許聚合初始化,但會將類似的問題標記為編譯錯誤。 假設我對上面 C++ 代碼的假設是正確的,是否有一種語言結構可以將缺少的初始化值識別為錯誤?

只有Aggregate Classes支持以這種方式初始化變量。

如果您添加構造函數,那么問題就會消失,但是您需要稍微更改語法,並且您將失去將struct存儲在union中的能力(除其他外)。

struct sampleData
{
    sampleData(int x, int y) : x(x), y(y) {}
    int x;
    int y;
};

sampleData sample( 1, 2 );

添加z (並更改構造函數)會將sample( 1, 2 )標記為編譯錯誤。

是的,您離開初始化列表的任何元素都將被初始化為零(對於 POD 標量類型)或使用它們的默認構造函數(對於類)。

此處引用了 C 標准中的相關語言:

[6.7.8.21] 如果大括號括起來的列表中的初始值設定項少於聚合的元素或成員,或者用於初始化已知大小數組的字符串文字中的字符少於數組中的元素,則聚合的其余部分應隱式初始化,與具有 static 存儲持續時間的對象相同。

我確信有人比我在 C++ 規范之一中找到相應的語言更有動力......

請注意,這意味着 POD 標量元素的初始化就像您寫了“= 0”一樣。 這意味着它將正確初始化指向 NULL 的指針並浮動到 0.0,即使它們的表示不是全零字節。 這也意味着它是遞歸工作的; 如果您的結構包含一個結構,則內部結構也將被正確初始化。

作為 Nemo 對 C 標准的回答的后續,這里是 C++03 標准所說的:

§8.5.1/7:

如果列表中的初始化器少於聚合中的成員,則每個未顯式初始化的成員都應進行值初始化。

§8.5/5:

T類型的 object 進行值初始化意味着:

  • 如果T是具有用戶聲明的構造函數的 class 類型,則調用T的默認構造函數(如果T沒有可訪問的默認構造函數,則初始化格式錯誤);
  • 如果T是沒有用戶聲明的構造函數的非聯合 class 類型,則T的每個非靜態數據成員和基類組件都是值初始化的;
  • 如果T是一個數組類型,那么每個元素都是值初始化的;
  • 否則,object 被零初始化

T類型的 object 進行零初始化意味着:

  • 如果T是標量類型,則將 object 設置為轉換為T的值0 (零);
  • 如果T是非聯合 class 類型,則每個非靜態數據成員和每個基類子對象都初始化為零;
  • 如果T是聯合類型,則對象的第一個命名數據成員)初始化為零;
  • 如果T是數組類型,則每個元素都初始化為零;
  • 如果T是引用類型,則不執行初始化。

為什么不使用

sampleData sample = { x: 1, y:2 } ;

?

但是您仍然會遇到z被初始化為不可預測值的問題,因此最好定義一個將所有變量設置為明確定義的值的構造函數。

暫無
暫無

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

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