4

可能重复:
以下短语在 C++ 中是什么意思:零、默认和值初始化?

我对 C++ 中的一个问题感到困惑。

使用默认构造函数在堆栈上创建对象时,我认为以下两种语法符号中的任何一种都会给出相同的结果:

class MyClass { public: int i; }
int main()
{
  MyClass a = MyClass();
  MyClass b;
}

但是,第一种语法将字段初始化为零,而第二种语法使字段未初始化。所以我的问题是:

  1. 为什么会这样?我认为 C++ 中的字段不应该被自动初始化。
  2. 两种语法之间还有其他区别吗?
  3. 这些语法变体是否有单独的名称来区分它们?

我目前正在使用 Microsoft Visual C++ 2010 Express。谢谢!

4

2 回答 2

7

首先,您从 的值初始化实例复制初始化 。来自 C++03 标准,§8.5/7:aMyClass

初始值设定项为空括号集的对象,即 (),应进行值初始化。

从 §8.5/5 开始:

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

  • ifT是具有用户声明的构造函数的类类型,则调用 for 的默认构造函数(如果没有可访问的默认构造函数T,则初始化格式错误);T
  • 如果T是没有用户声明的构造函数的非联合类类型,则每个非静态数据成员和基类组件T都是值初始化的;
  • 如果T是数组类型,则每个元素都是值初始化的;
  • 否则,对象被零初始化

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

  • 如果T是标量类型,则将对象设置为0(零)转换为的值T
  • 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都进行零初始化;
  • 如果T是联合类型,则对象的第一个命名数据成员)为零初始化;
  • 如果T是数组类型,则每个元素都初始化为零;
  • 如果T是引用类型,则不执行初始化。

在第二种情况下,如果不是 POD 类型,则以一种b会导致它为default-initialize的方式声明——第 8.5/5 节:MyClass

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

  • 如果T是非 POD 类类型,T则调用T的默认构造函数(如果没有可访问的默认构造函数,则初始化为非良构);
  • 如果T是数组类型,则每个元素都是默认初始化的;
  • 否则,对象被零初始化。

但是,因为MyClass是 POD 类型,b所以未初始化——第 8.5/9 节:

如果没有为对象指定初始化程序,并且该对象是(可能是 cv 限定的)非 POD 类类型(或其数组),则该对象应默认初始化;如果对象是 const 限定类型,则基础类类型应具有用户声明的默认构造函数。否则,如果没有为非静态对象指定初始化器,则该对象及其子对象(如果有)具有不确定的初始值;如果对象或其任何子对象是 const 限定类型,则该程序是非良构的。

于 2011-06-28T19:29:14.383 回答
-1

基本上,这是语言中(相对)简单的 WTF,默认情况下不会初始化原始类型。第一种语法显式地初始化它们——第二种没有。用户定义的类型总是会被初始化,所以只有在构造函数中不初始化才有意义,不调用需要的UDT的init函数会报错。

不做任何疯狂事情的​​ UDT 不需要第一种语法,使用第二种语法是正常的。

于 2011-06-28T19:23:10.110 回答