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

C++ C+中的聚合初始化安全性+;,c++,ada,aggregate-initialization,C++,Ada,Aggregate Initialization,假设我有以下结构: struct sampleData { int x; int y; }; 使用时,我希望将sampleData类型的变量初始化为已知状态 sampleData sample = { 1, 2 } 稍后,我决定需要在我的sampleDatastruct中存储额外的数据,如下所示: struct sampleData { int x; int y; int z; }; 我的理解是,我的pre-z数据结构

假设我有以下结构:

struct sampleData
{
       int x;
       int y;
};
使用时,我希望将
sampleData
类型的变量初始化为已知状态

sampleData sample = { 1, 2 } 
稍后,我决定需要在我的
sampleData
struct中存储额外的数据,如下所示:

struct sampleData
{
       int x;
       int y;
       int z;
};
我的理解是,我的pre-
z
数据结构中留下的两个字段初始化仍然是一个有效语句,将被编译,用默认值填充缺少的字段


这种理解正确吗?我最近一直在Ada中工作,它也允许聚合初始化,但会将类似的问题标记为编译错误。假设我对上面C++代码的假设是正确的,有没有一个语言构造可以将缺失的初始化值识别为错误? 是的,您从初始化列表中删除的任何元素都将被初始化为零(对于POD标量类型)或使用其默认构造函数(对于类)

引用C标准中的相关语言:

[6.7.8.21]如果大括号内的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同

<>我确信在我的C++中,有人比我更能找到相应的语言……
注意,这意味着POD标量元素被初始化,就像您写“=0”一样。这意味着它将正确地初始化指向NULL的指针,并将其浮动到0.0,即使它们的表示形式并非都是零字节。它还意味着它是递归工作的;如果您的结构包含一个结构,则内部结构也将正确初始化。

仅支持以这种方式初始化变量

如果您添加了构造函数,那么问题就消失了,但您需要稍微更改语法,并且您将失去将
结构
存储在
联合
中的能力(除其他外)

添加
z
(并更改构造函数)将
示例(1,2)
标记为编译错误。

为什么不使用

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


但是您仍然会遇到初始化为不可预测值的问题,因此最好定义一个构造函数,将所有变量设置为定义良好的值。

作为Nemo对C标准的回答的后续,C++03标准是这样说的:

§8.5.1/7:

如果列表中的初始值设定项少于聚合中的成员,则未显式初始化的每个成员都应进行值初始化

§8.5/5:

T
类型的对象进行值初始化意味着:

  • 如果
    T
    是具有用户声明的构造函数的类类型,则调用
    T
    的默认构造函数(如果
    T
    没有可访问的默认构造函数,则初始化是错误的)
  • 如果
    T
    是一个没有用户声明构造函数的非联合类类型,那么
    T
    的每个非静态数据成员和基类组件都是初始化值
  • 如果
    T
    是数组类型,则每个元素都初始化了值
  • 否则,对象初始化为零
T
类型的对象初始化为零意味着:

  • 如果
    T
    是标量类型,则将对象设置为
    0
    (零)的值,并转换为
    T
  • 如果
    T
    是非联合类类型,则每个非静态数据成员和每个基类子对象初始化为零
  • 如果
    T
    是联合类型,则对象的第一个命名数据成员)初始化为零
  • 如果
    T
    是数组类型,则每个元素初始化为零
  • 如果
    T
    是参考类型,则不执行初始化

因为问题是标签<代码> C++ +代码>,而不是C++ C++,那么是<代码> SAMPLEDATA示例= { 1, 2 } < /Cuth> C++吗?实际上它是被称为“聚合初始化”。现在答案是:为了使用Struts,我怀疑C标准对C++是相当封闭的。spec@Greg不,实际上,在C++中,如果对象是POD类型,则具有静态存储持续时间的对象初始化为零,但根据其定义的方式进行初始化;另一方面,从聚合初始值设定项中省略的数据成员总是值初始化的。+1。在z有一个默认值的地方添加一个(x,y,z)构造函数,可以让你两全其美。即使Z的默认值为零,它也有助于记录您正在做的事情,不,只有聚合类才支持以这种方式初始化变量。所有聚合类都是POD类型,但并非所有的POD类型都是聚合类,因此并非所有的POD类型都支持聚合初始化。@ildjam:感谢您的澄清。我已经更新了我的答案。这也是我的答案(so+1),但这样做有一个缺点。从技术上讲,这使得他的
struct
不再是一个吊舱。然而,在实践中,大多数编译器似乎将其视为一个POD,只要对其执行的操作仅此而已。我把这种结构称为“pseudoPODs”@T.E.D.:在C++0x中,这样的东西有一个正式的名称--“标准布局类”。@Nemo:我只是复制并粘贴了我的另一个已经格式化的答案。无需任何努力:-P
sampleData sample = { x: 1, y:2 } ;