3

以下来自指定初始化程序cppref

struct A { int x; int y; int z; };
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0

默认情况下,所有基本类型都是默认初始化的,而不是 C++ 中的零初始化。

为什么指定的初始化器对数据成员进行零初始化?

4

2 回答 2

8

b.y将从一个空的初始化列表初始化,效果为零初始化0.

对于非联合聚合,未提供指定初始化程序的元素的初始化方式与上述相同,当初始化程序子句的数量小于成员数时(提供默认成员初始化程序,否则为空列表初始化) :

struct A {
  string str;
  int n = 42;
  int m = -1;
};
A{.m=21}  // Initializes str with {}, which calls the default constructor
          // then initializes n with = 42
          // then initializes m with = 21

根据标准,[dcl.init.aggr]/5

对于非联合聚合,不是显式初始化元素的每个元素都按如下方式初始化:

  • (5.1) 如果元素具有默认成员初始化程序 ( [class.mem] ),则从该初始化程序初始化该元素。

  • (5.2) 否则,如果元素不是引用,则从空初始化列表 ( [dcl.init.list] ) 复制初始化该元素。

  • (5.3) 否则,程序是非良构的。

于 2021-11-29T09:33:13.040 回答
4

在列表初始化(如果是聚合的情况下是聚合初始化)中没有初始化程序(并且没有默认成员初始化程序)的子对象A值初始化的(在子对象的情况下是零初始化int)。它们不是默认初始化的。

在指定初始化程序之前就是这种情况,并且在您使用指定初始化程序时仍然是这种情况。例子:

struct A { int x; int y; int z; };
A b0;                  // default i.e. no initialisation for x,y,z
A b1 {};               // x, y and z are value initialised
A b2 {1};              //    y and z are value initialised
A b3 {.x = 1, .z = 2}; //    y       is  value initialised

这同样适用于数组,尽管不幸的是在标准 C++ 中没有指定的初始化器:

int arr0[3];          // default i.e. no initialisation
int arr1[3] {};       // all are value initialised
int arr2[3] {42};     // all but first are value initialised
于 2021-11-29T09:40:49.873 回答