这在3.8:7中明确批准:
3.8 对象的生存期 [basic.life]
7 - 如果在一个对象的生命期结束后[...],一份新的对象被创建在原始对象所占用的存储位置上,那么指向原始对象的指针[...]可以用来操作新的对象,如果满足以下要求: (各种要求在这种情况下得到满足)
给出的示例是:
struct C {
int i;
void f();
const C& operator=( const C& );
};
const C& C::operator=( const C& other) {
if ( this != &other ) {
this->~C(); // lifetime of *this ends
new (this) C(other); // new object of type C created
f(); // well-defined
}
return *this;
}
const
或引用数据成员(也不能其成员具有,因为当你将此技巧应用于一个对象时,你正在将相同的技巧应用于其所有成员及其成员等等)。这些数据成员可能是导致某人认为“我无法改变对象,所以需要销毁和重新创建它”的主要原因,但他们是错误的。 - Steve Jessop严格来说,这是可以的。但是,如果没有极度小心,它将变成一个可怕的UB(未定义行为)。例如,任何调用此方法的派生类都无法重新构造正确的类型-或者当Class()
抛出异常时会发生什么。此外,这实际上并没有实现任何东西。
虽然不是严格的UB,但它是一堆垃圾和失败,应该立即焚毁。
object
指针在任何时候都不会失效(假设您的析构函数没有调用delete this
)。您的对象从未被释放,它只是调用了它的析构函数,也就是说,它已经清理了它的内部状态(关于实现,请注意标准严格定义了对象在析构函数调用后被销毁)。由于您使用了placement new在完全相同的地址实例化新对象,因此技术上是可以的。话虽如此,这仅仅是学习代码的有趣案例,作为生产代码,这是可怕的 :)如果在对象的生命周期结束之后,在重新使用或释放原始对象占用的存储器之前,在原始对象所占用的存储位置上创建一个新对象,则指向原始对象的指针、引用原始对象的引用或原始对象的名称将自动引用新对象,并且一旦新对象的生命周期开始,就可以用来操作新对象[...]
指针只知道它的地址,一旦你确认新对象的地址是指针所指向的地址,答案就是肯定的。
有些情况下,人们会认为地址不会改变,但在某些情况下确实会改变,例如使用C语言的realloc()
函数。但这是另外一个故事了。
realloc
究竟与任何事情有什么关系? - Puppy