5

我正在使用 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();
}
4

1 回答 1

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),然后运行默认构造函数。

于 2015-02-08T08:07:20.027 回答