默认初始化与值初始化

时间:2011-11-20 18:19:11

标签: c++ initialization

从这个answer开始,在C ++ 03中,如果省略(),则默认初始化POD类型,否则它是值初始化的。

// POD type
struct foo {
     int x;
};

// value-initialized
new foo();

但是如果提供了用户定义的构造函数,下面的任何对象是否会被视为默认值或值初始化?

// non-POD type
struct bar {
     bar(int x = 0):x(x) {}
     int x;
};

new bar();
new bar(42);

2 个答案:

答案 0 :(得分:3)

  

在C ++ 03中,如果省略(),则POD类型默认初始化,否则进行值初始化。

事实并非如此。根据C ++ 03规范,第8.5 / 9节,如果没有为非静态POD类型对象指定初始化器,那么它及其子对象“具有不确定的初始值”。这与与默认初始化相同。默认初始化与POD类型的值初始化相同,这意味着对象是零初始化(8.5 / 5),但这只能在存在空初始化器的情况下发生(即空括号)每8.5 / 7)。因此,您只能使用空的初始化程序对POD类型进行默认和/或值初始化。如果未指定初始化程序,则不会发生非静态POD类型的默认初始化。

在第二个示例中,对于具有用户定义构造函数的非POD类型,如果省略了value-initializer(括号)符号,则在技术上会进行默认初始化。换句话说:

bar* ptr_a = new bar; //default initialization
bar* ptr_b = new bar(); //value initialization

请记住,对于非POD结构或类类型,如果存在用户定义的构造函数,默认初始化和值初始化,则每8.5 / 5,都会调用用户定义的构造函数。所以最后,对于你声明它的类型bar,默认值和值初始化最终会做同样的事情。

答案 1 :(得分:2)

如果您的类具有用户定义的默认构造函数,则默认值和值初始化都会导致调用该构造函数。接下来发生的事情取决于构造函数:

struct UDT
{
  int a;
  int b;
  Foo c;
  Foo d;
  UDT() : a(), c() {}
};

UDT的对象的默认值和值初始化都会导致UDT::aUDT::c进行值初始化(因此a为零)因为初始化列表这样说,虽然UDT::bUDT::d本身是默认初始化的(因此b未初始化,而d递归地应用相同的逻辑。)

有关初始化的详细信息,请参见8.5,初始化列表请参见12.6.2(特别是第8节)。

相关问题