用C ++编写堆栈对象 - 替代语法

时间:2011-06-28 19:20:51

标签: c++ object syntax stack creation

  

可能重复:
  What do the following phrases mean in C++: zero-, default- and value-initialization?

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

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

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

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

  1. 为什么会这样?我认为C ++中的字段不应该被自动初始化。
  2. 两种语法之间是否还有其他差异?
  3. 这些语法变体是否有不同的名称以区分它们?
  4. 我目前正在使用Microsoft Visual C ++ 2010 Express。 谢谢!

2 个答案:

答案 0 :(得分:7)

首先,您从a值初始化实例中复制初始化 MyClass。从C ++ 03标准,§8.5/ 7:

  

一个对象,其初始化程序是一组空的括号,即(),应进行值初始化。

来自§8.5/ 5:

  

value-initialize T类型的对象意味着:

     
      
  • 如果T是具有用户声明的构造函数的类类型,则调用T的默认构造函数(如果T没有可访问的默认值,则初始化不正确构造函数);
  •   
  • 如果T是没有用户声明的构造函数的非联合类类型,那么T的每个非静态数据成员和基类组件都是值初始化的; < /强>
  •   
  • 如果T是数组类型,则每个元素都是值初始化的;
  •   
  • 否则,该对象为零初始化
  •   
     

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

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

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

  

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

     
      
  • 如果T是非POD类类型,则T的默认构造函数称为(如果T具有T,则初始化格式错误没有可访问的默认构造函数);
  •   
  • 如果MyClass是数组类型,则每个元素都是默认初始化的;
  •   
  • 否则,该对象为零初始化。
  •   

但是,由于b是POD类型,{{1}}未初始化 - §8.5/ 9:

  

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

答案 1 :(得分:-1)

基本上,这是语言中的(相对)简单的WTF,默认情况下不会初始化基本类型。第一种语法显式初始化它们 - 第二种语法没有。用户定义的类型将始终被初始化,因此只有在构造函数中不对其进行初始化时才有意义,如果不调用需要它们的UDT的init函数,则会出错。

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