我使用的是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();
}
答案 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),然后是默认值构造函数运行。