我非常确定内置类型的数组是统一初始化的,而 UDT 数组是默认初始化的。

int foo[5]; // will contain junk
Foo foo[5]; // will contain 5 Foo objects that are default initialized

无论数组是在堆栈还是堆上分配,都会发生这种情况。

然而,我发现很难找到这方面的权威来源。比亚恩指出:

“数组和结构的成员是否默认初始化取决于数组或结构是否是静态的”,这并没有告诉我太多信息。

我也试图在标准中找到一些东西,但到目前为止还没有成功。

有谁知道有权威来源可以证实上述情况吗?

有帮助吗?

解决方案

ISO C++03 具有相当的权威性:

POD 结构是一个聚合类,它没有非 POD 结构、非 POD 联合(或此类类型的数组)类型的非静态数据成员或引用,并且没有用户定义的复制赋值运算符,也没有用户定义的析构函数。类似地,POD-union 是一个聚合联合,它没有非 POD-struct、非 POD-union(或此类类型的数组)或引用类型的非静态数据成员,并且没有用户定义的复制赋值运算符并且没有用户定义的析构函数。POD 类是 POD 结构或 POD 联合的类。

算术类型 (3.9.1)、枚举类型、指针类型和指向成员类型的指针 (3.9.2) 以及这些类型的 cv 限定版本 (3.9.3) 统称为标量类型。标量类型、POD 结构类型、POD 联合类型(第 9 条)、此类类型的数组以及这些类型的 cv 限定版本 (3.9.3) 统称为 POD 类型。

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

  • 如果 T 是标量类型 (3.9),则将对象设置为转换为 T 的值 0(零);
  • 如果t是非工会类类型,则每个非静态数据成员和每个基级子对象均为零始于。
  • 如果 T 是联合类型,则对象的第一个命名数据成员为零初始化;
  • 如果 T 是数组类型,则每个元素都初始化为零;
  • 如果 T 是引用类型,则不执行初始化。

默认初始化 T 类型的对象意味着:

  • 如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是格式错误的);
  • 如果 T 是数组类型,则每个元素都默认初始化;
  • 否则,该对象将被零初始化。

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

  • 如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化格式错误);
  • 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都进行值初始化;
  • 如果 T 是数组类型,则每个元素都是值初始化的;
  • 否则,该对象将被零初始化

每个静态存储持续时间的对象应在程序启动时在任何其他初始化发生之前进行零初始化。[笔记:在某些情况下,稍后会进行额外的初始化。]

其初始化器是一组空括号(即 ())的对象应进行值初始化。

如果没有为对象指定初始化程序,并且该对象属于(可能是 cv 限定的)非 POD 类类型(或其数组),则该对象应默认初始化;如果对象是 const 限定类型,则底层类类型应具有用户声明的默认构造函数。否则,如果没有为非静态对象指定初始值设定项,则该对象及其子对象(如果有)将具有不确定的初始值);如果对象或其任何子对象是 const 限定类型,则程序格式错误。

对于你的例子, int 绝对是 POD 类型(它是算术类型),因此是类型的局部或字段 int, 在没有初始化器的情况下,将具有不确定的值。为了 Foo, ,这取决于它是如何定义的——粗略地说,如果它没有构造函数,并且它的所有成员都是 POD 类型,那么它本身就是一个 POD 类型,也不会发生初始化。否则,将调用默认构造函数。即便如此,这并不意味着 会员 已初始化 - 规则是递归的,因此非 POD 类型的 POD 成员不会被初始化,除非该类型的构造函数专门执行此操作(在其初始化程序列表中)。

静态变量和字段在所有情况下都将被零初始化。请注意,这也适用于非 POD - 这意味着类类型的静态变量保证将所有字段递归设置为 (T)0 甚至在其构造函数运行之前。

默认初始化任何聚合 POD 类型的一个方便技巧是使用 {} 在初始化程序中 - 请注意它适用于结构和数组:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

其他提示

它在C ++标准中说,在8.5.9中:

  

如果没有为a指定初始值设定项   对象,对象是(可能是   cv-qualified)非POD类类型(或   对象应该是   默认初始化;如果对象是   const限定类型,   基础类型应具有   用户声明的默认构造函数。   否则,如果没有初始化器   为非静态对象指定的   对象及其子对象(如果有)   具有不确定的初始值。

“数组和结构的成员是否默认初始化取决于数组或结构是否是静态的”

这是权威的,尽管它可能更清楚:

  • 数组和结构声明为 static 被初始化为零。
  • 内置类型的局部数组和结构(IE。 没有构造函数的类型)不会被初始化。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top