C ++ 14非聚合上的统一初始化

时间:2015-02-08 07:50:24

标签: c++ c++14 uniform-initialization

我使用的是Visual C ++ 2013.当该类是聚合时,它是零初始化的。如果它是非聚合的,它似乎是默认初始化并且不确定。那是为什么?

#include <iostream>

using namespace std;

class Test_1
{
public:
    int i;
    void f(){};
};

class Test_2
{
public:
    int i;
    virtual void f(){};
};

int main()
{
    Test_1 t1{};
    Test_2 t2{};

    cout<<t1.i<<endl; //0
    cout<<t2.i<<endl; //-858993460

    getchar();
}

1 个答案:

答案 0 :(得分:4)

如果您的编译器正在执行此操作,则它已损坏。

[dcl.init.list] / p3(所有报价均来自N4140):

  

定义了T类型的对象或引用的列表初始化   如下:

     
      
  • 如果T是聚合,则执行聚合初始化(8.5.1)。
  •   
  • 否则,如果初始化列表没有元素,T是具有默认构造函数的类类型,则对象为   值初始化。
  •   
  • [...]
  •   

[dcl.init] / P8:

  

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

     
      
  • 如果T是一个(可能是cv限定的)类类型(第9条),没有默认构造函数(12.1)或者是默认构造函数   用户提供或删除,然后该对象被默认初始化;
  •   
  • 如果T是一个(可能是cv限定的)类类型而没有用户提供或删除的默认构造函数,那么对象是   零初始化和语义约束   检查默认初始化,如果T具有非平凡的默认值   构造函数,该对象是默认初始化的;
  •   
  • 如果T是数组类型,则每个元素都是值初始化的;
  •   
  • 否则,该对象为零初始化。
  •   

Test_2不是聚合,因此t2应该已经过值初始化。反过来,由于Test_2的默认构造函数不是用户提供的,因此t2应该首先进行零初始化(导致t2.i初始化为0),然后是默认值构造函数运行。