在赋值运算符中析构和重建对象是一个坏主意吗?

问题描述

自从使用 C++11 标准以来,我就很少编程,所以我仍在学习一些较新的习语以及如何使用它们。

我一直在思考如何编写高效的赋值运算符,但我刚刚发现了 Placement new 的工作原理。

所以现在我正在考虑通过 (1) 销毁对象和 (2) 使用放置 new 来调用复制构造函数来编写赋值运算符,例如:

MyClass& MyClass::operator=(const MyClass& other)
{
    if (&other == this)
        return (*this);

    this -> ~MyClass();
    return *(new (this) MyClass(other));
}

通常我不会在销毁对象后使用它。但是,我立即重建它。这个习语使用起来安全和优雅吗?或者这是一个可怕的想法,我应该立即

delete this;

解决方法

这种方法并不新鲜,人们以前也尝试过。正如评论中所述(其余的不太严重),主要问题是在调用复制构造函数期间可能引发异常。

如果发生这种情况,您最终会陷入非常糟糕的境地——您确实已经调用了析构函数,因此该对象不再有效,并且无法撤消。即使你捕捉到异常,仍然没有很好的追索权,因为你无法恢复对象。

还有一些类在调用析构函数之前需要特定的先决条件(std::thread 是一个主要的例子)。虽然我个人不喜欢这样,但这些类是存在的。

如果您是为自己的完全控制的类执行此操作,并且您知道事实复制构造函数不会抛出(并且最好这样注释),并且可以接受类的随机销毁,则这种方法是可行的- 虽然,通常不值得。