C++ 03中default-initialize和value-initialize之间的区别?

Mar*_*som 8 c++ standards default-value default-constructor

我一直认为创建一个新对象总是会调用一个对象的默认构造函数,而构造函数是显式的还是由编译器自动生成的没有区别.根据对这个不同问题的高度重视的答案,这在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.
Run Code Online (Sandbox Code Playgroud)

谁能告诉我:

  1. 为什么标准发生了变化,即这给了什么优势,或者现在可能有什么优势;
  2. "default-initialize"和"value-initialize"这两个术语是什么意思?
  3. 该标准的相关部分是什么?

Dav*_*eas 3

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

\n

这属于“只为你想要的东西付费”的语言哲学,并且在所有与 C 兼容的类型中与 C 兼容。另一方面,您可以请求值初始化,这相当于为具有它的对象调用默认构造函数初始化以0转换为其余子对象的适当类型。

\n

这在 \xc2\xa78.5 初始化程序中进行了描述,并且导航起来并不简单。零初始化默认初始化值初始化的定义是第 5 段:

\n
\n

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

\n

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

\n

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

\n

\xe2\x80\x94 如果 T 是联合类型,则对象\xe2\x80\x99s 第一个命名数据成员89) 被零初始化;

\n

\xe2\x80\x94 如果 T 是数组类型,则每个元素均初始化为零;

\n

\xe2\x80\x94 如果 T 是引用类型,则不执行初始化。

\n

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

\n

\xe2\x80\x94 如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是格式错误的);

\n

\xe2\x80\x94 如果 T 是数组类型,则每个元素默认初始化;

\n

\xe2\x80\x94 否则,该对象被零初始化。

\n

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

\n

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

\n

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

\n

\xe2\x80\x94 如果 T 是数组类型,则每个元素都是值初始化的;

\n

\xe2\x80\x94 否则,该对象被零初始化

\n

调用引用类型实体的默认初始化或值初始化的程序是不正确的。如果 T 是 cv 限定类型,则 T 的 cv 非限定版本将用于这些零初始化、默认初始化和值初始化的定义。

\n
\n