#include <cstdlib>
struct B {
virtual void f();
void mutate();
virtual ~B();
};
struct D1 : B { void f(); };
struct D2 : B { void f(); };
void B::mutate() {
new (this) D2; // reuses storage — ends the lifetime of *this
f(); // undefined behavior - WHY????
... = this; // OK, this points to valid memory
}
我需要解释为什么f()
invokation有UB? new (this) D2;
重用存储,但它也调用D2
的构造函数,并自启动新对象的生命周期。 f()
等于this -> f()
。 这就是我们只需拨打D2
的成员函数f()
。谁知道它为什么是UB?重用新对象的存储开始生命周期吗?
Placement-new应该在大多数派生类中使用,并将它们替换为相同类型的对象。这是您拥有UB的另一个原因,因为您不仅要替换基类子对象,而且要用不同类型的对象替换它。 – 0x499602D2 2014-09-04 04:51:04
@ 0x499602D2标准的18.6.1.3定义了这样的位置的行为 - 新的,但没有说任何关于假设在大多数派生类中使用**以及创建相同类型的对象** – 2014-09-04 04:55:06
3.8“如果在一个对象的生命周期已经结束,一个新的对象被创建在原始对象所占据的存储位置,[...]原始对象的名称将自动引用新对象[...]用于在以下情况下操作新对象:原始对象是类型T的派生对象(1.8),新对象是类型T的派生对象(即,它们不是基类子对象)。 – 0x499602D2 2014-09-04 04:58:02