C++ 11中类数据成员的默认初始化

Jae*_*ege 7 c++ c++11

我对类数据成员的默认初始化感到困惑.这是示例代码.

#include <iostream>
#include <vector>

class A {
public:
  int i;
  A() {}
};

A a1;
A aa1[3];
std::vector<A> av1(3);

int main()
{
  A a2;
  A aa2[3];
  std::vector<A> av2(3);
  std::cout << a1.i << " " << a2.i << std::endl;          // 0         undefined
  std::cout << aa1[0].i << " " << aa2[0].i << std::endl;  // 0         undefined
  std::cout << av1[0].i << " " << av2[0].i << std::endl;  // undefined undefined
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,只有a1.iaa1[0~2].i被初始化为0,而其他的是未初始化的.我不知道为什么会这样.

具体来说,我已经知道的是(来自"C++ Primer"):

  • 初始化过程是:

    • a1并且a2默认初始化.
    • 的每一个元素aa1,并aa2默认情况下初始化.
    • 每个元素av1av2都被初始化了.
  • 默认初始化的过程是:

    • 检查变量是内置类型还是类类型.
    • 对于内置类型,如果变量在任何函数体外,则将其初始化为0,否则该值未定义.
    • 对于类类型,如果类具有默认ctor,则调用它,否则它是编译错误.
  • 值初始化的过程是:

    • 检查变量是内置类型还是类类型.
    • 对于内置类型,它被初始化为0.
    • 对于类类型,它是默认初始化的.(我认为这意味着如果该类具有默认的ctor,则调用它,否则它是编译错误.)

因此,当A::A()调用ctor时,数据成员如何A::i初始化(我猜它是默认初始化的)?为什么只有a1.iaa1[0~2].i被初始化为0,而其他人是未初始化的?

leg*_*s2k 7

当构造函数 A::A() 被调用时,数据成员 A::i 如何初始化

如果未提供初始化程序,则应用默认初始化规则。你的构造函数没有初始化,A::i所以它没有初始化;它的价值是不确定的。毫无疑问。摘自有关默认初始化文档

如果 T 是类类型,则考虑构造函数并针对空参数列表进行重载决议。调用选定的构造函数(默认构造函数之一)来为新对象提供初始值。


为什么只有 a1.i 和 aa1[0~2].i 被初始化为 0,而其他的则未初始化?

全局数据存储器被初始化为零,即整个部分都被清零,所以你会看到 global A::is 被初始化为0。请注意,构造函数不会这样做。文档摘录:

静态初始化

[...]

2) 对于所有其他非局部静态和线程局部变量,零初始化发生。实际上,将要进行零初始化的变量放置在程序映像的 .bss 段中,该段不占用磁盘空间,并在加载程序时由操作系统清零。

然而,对于vector,它vector本身在非本地静态内存中,而它的元素在自由存储(堆)中分配,因此它们的成员也未初始化。