默认初始化与值初始化的区别

5

根据这篇回答所述,在 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);

1
在你的例子中,对bar构造函数的两次调用都会在初始化x时提供一个值。 - Chad
2个回答

3
在C++03中,如果省略了(),POD类型将被默认初始化;否则,它将被值初始化。但情况并非如此。根据C++03规范第8.5/9节,如果未为非静态POD类型对象指定初始化程序,则它及其子对象“具有不确定的初始值”。那不等同于默认初始化。对于POD类型, 默认初始化与值初始化相同,这意味着该对象将被初始化为零(8.5/5),但只有在存在空初始化符号(即空括号8.5/7)的情况下才会发生。因此,只能使用空初始化符号来默认和/或值初始化POD类型。当未指定初始化程序时,非静态POD类型的默认初始化不会发生。
在第二个例子中,对于具有用户定义的构造函数的非POD类型,如果省略值初始化程序(括号),则技术上将进行默认初始化。换句话说:
bar* ptr_a = new bar; //default initialization
bar* ptr_b = new bar(); //value initialization

请注意,使用非POD结构体或类类型时,如果存在用户定义的构造函数,则默认初始化和值初始化都调用用户定义的构造函数,根据8.5/5的规定。因此,最终,对于您声明的类型bar,默认初始化和值初始化会执行相同的操作。

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 条)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接