没有构造函数的 C++ 零初始化

Joj*_*ino 1 c++ constructor struct initialization

我不明白关于其成员具有默认值的结构的零初始化会发生什么。

如果我有这些结构:

struct A {
  int *a;
  int b;
};

struct B {
  int *a;
  int b;
  B() : b(3) {}
};

struct C {
  int *a;
  int b = 3;
};
Run Code Online (Sandbox Code Playgroud)

毫无疑问,我们可以说的是:

  • A a; 使所有字段未初始化
  • A a{}; 是 {nullptr, 0}
  • B b;并且B b{};都是 {garbage, 3} (构造函数被调用)

现在还不清楚当我执行以下操作时会发生什么,以下是使用 gcc 的结果:

C c; // {garbage, 3}
C c{}; // {nullptr, 3}
Run Code Online (Sandbox Code Playgroud)

现在的问题是:不C c{}; 保证C::a被初始化为nullptr,换句话说,不会有像在默认成员C仍为零初始化其他成员,如果我明确构造对象一样C c{};

因为如果我有一个构造函数与C(如 in B)执行相同的操作,则不会发生什么,其他成员初始化为零,但为什么呢?B和 和有C什么区别?

Igo*_*nik 5

从 C++14 开始,C是一个聚合(如A),C c{}语法执行聚合初始化。这部分包括:

[dcl.init.aggr]/8如果列表中的初始化子句少于非联合聚合中的元素,则每个未显式初始化的元素按如下方式初始化:
(8.1) — 如果元素具有默认成员初始化器(12.2),元素从该初始化器初始化。
(8.2) — 否则,如果元素不是引用,则从空的初始化列表 (11.6.4) 中复制初始化该元素。
(8.3) — 否则,程序格式错误。

所以C c{};相当于C c{{}, 3};. int*用空列表初始化成员会导致它被初始化为零。

在 C++11 中,C不是聚合(具有默认成员初始值设定项是不合格的),并且C c{};调用隐式定义的构造函数,该构造函数使c.a成员未初始化。

在标准的所有版本中,B由于用户定义的构造函数,它不是聚合。B b{};调用该构造函数,该构造函数显式初始化b成员并选择a未初始化。