7

说我有以下内容:

struct A
{
   int x;
};

//...
A* aOriginal = new A();  //value construct aOriginal
assert( aOriginal->x == 0 );

A* aSecond = new (aOriginal) A;
assert( aSecond->x == 0 );

即使aSecond没有进行值初始化,第二个断言是否也能保证成立?从逻辑上讲,它应该,因为内存没有被覆盖,但它是由标准指定的吗?

4

1 回答 1

9

不。

当您在同一存储位置构造第二个对象时,前一个对象的生命周期结束(第 3.8/1 节):

[...] 类型对象的生命周期在以下情况下T结束:

  • 如果T是具有非平凡析构函数(第 12.4 节)的类类型,则析构函数调用开始,或者
  • 对象占用的存储空间被重用或释放。

创建第二个对象时,由于A具有隐式默认构造函数,因此该x成员被默认初始化,因此不执行初始化(第 8.5/6 节):

默认初始化类型的对象T意味着:

  • [...]

  • 否则,不执行初始化。

这意味着该对象具有不确定的价值(§5.3.4/15):

创建类型对象的new表达式T按如下方式初始化该对象:

  • 如果省略new-initializer,则对象为默认初始化(第 8.5 节);如果不执行初始化,则对象具有不确定的值。

如果您认为该值不是不确定的,因为您之前在该存储位置初始化了另一个对象:标准也放弃了这种可能性,即前一个对象的属性在其生命周期结束后不再适用(第 3.8/3 节) :

本国际标准中赋予对象的属性仅在其生命周期内适用于给定对象。

于 2012-07-30T21:16:58.180 回答