8

我一直认为创建一个新对象总是会调用一个对象上的默认构造函数,而构造函数是显式的还是编译器自动生成的并没有区别。根据这个备受推崇的对不同问题的回答,这在 C++98 和 C++03 之间发生了微妙的变化,现在的工作方式如下:

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B;   // default-initializes (leaves B::m uninitialized)
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.

谁能告诉我:

  1. 为什么要更改标准,即这有什么好处,或者现在有什么以前没有的可能;
  2. “默认初始化”和“值初始化”这两个术语究竟代表什么?
  3. 标准的相关部分是什么?
4

1 回答 1

3

我不知道更改的基本原理(或标准之前的情况),但关于它是如何的,基本上默认初始化是调用用户定义的构造函数或什么都不做(这里有很多挥手:这是递归的应用于每个子对象,这意味着具有默认构造函数的子对象将被初始化,没有用户定义的构造函数的子对象将保持未初始化)。

这属于您想要的语言哲学的唯一支付,并且在所有与 C 兼容的类型中都与 C 兼容。另一方面,您可以请求value-initialization,这相当于为拥有它的对象调用默认构造函数,或者0为其余子对象初始化以转换为适当的类型。

这在 §8.5 Initializers 中进行了描述,并且导航并非易事。zero-initializedefault-initializevalue-initialize的定义在第 5 段:

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

— 如果 T 是标量类型(3.9),则将对象设置为转换为 T 的值 0(零);

— 如果 T 是非联合类类型,则每个非静态数据成员和每个基类子对象都被零初始化;

— 如果 T 是联合类型,则对象的第一个命名数据成员 89) 初始化为零;

— 如果 T 是数组类型,则每个元素都初始化为零;

— 如果 T 是引用类型,则不执行初始化。

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

— 如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是非良构的);

— 如果 T 是数组类型,则每个元素都是默认初始化的;

— 否则,对象被零初始化。

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

— 如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是错误的);

— 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都是值初始化的;

— 如果 T 是一个数组类型,那么每个元素都是值初始化的;

— 否则,对象被零初始化

要求对引用类型的实体进行默认初始化或值初始化的程序是错误的。如果 T 是 cv 限定类型,则 T 的 cv 非限定版本用于这些零初始化、默认初始化和值初始化的定义。

于 2011-08-16T21:26:53.017 回答