重置对象

Reset an object

本文关键字:对象      更新时间:2023-10-16

最近我经常通过使用operator=为其分配一个新值来重置对象。我的大多数课程都有一个copy constructoroperator=使用"复制和交换"习惯法定义。在大多数情况下,这工作正常,尽管效率不高,但这大多无关紧要。不过,有一种情况是这不起作用。当destructor需要在constructor新对象之前调用时。

注意:我使用它的大多数类都是不可复制的

class Foo
{
public:
    Foo() : m_i(0) {}
    Foo(int i) : m_i(i) {}
    Foo(Foo&& rhs);
    Foo& operator=(Foo rhs);
    friend void swap(Foo& lhs, Foo& rhs);
private:
    Foo(Foo& rhs) {}    // uncopyable object
    int m_i;
};
Foo::Foo(Foo&& rhs)
: Foo()
{
    swap(*this, rhs);
}
Foo& Foo::operator=(Foo rhs)
{
    swap(*this, rhs);
    return *this;
}
void swap(Foo& lhs, Foo& rhs)
{
    using std::swap;
    swap(lhs.m_i, rhs.m_i);
}
int main()
{
    Foo f(123);
    f = Foo(321);   // at one time both Foo(123) and Foo(321) exist in memory
}

然后我教过重写operator=首先手动调用destructor,然后执行swap(在这种情况下,rhs将由 const 引用获取)。然而,堆栈溢出上的这个答案让我不这么认为。

我真的很喜欢 operator= 来重置我的对象,因为代码很干净,并且与内置类型(如 int)的代码相同。它还使用constructordestructor的代码,因此不需要编写和维护额外的代码。

所以我的问题是:有没有办法实现我的目标,即使用干净的代码重置我的对象,而无需编写额外的代码,并在构造新对象之前破坏对象?

根据定义,如果将新值分配给旧对象,则在赋值发生之前已构造新值。

你的"旧对象"也没有真正被破坏。

所以没有。 没有办法。 不应该有:你不应该重新定义赋值运算符的"明显"行为。

但是除了波浪号和奇特的构造语法之外,放置新位置在这里可能会有所帮助,也许这段代码接近"干净":)

Foo old(a, b, c);
old.~Foo(); // explicit destruction
new (&old) Foo(d, e, f);

如果构造函数中的代码也需要由赋值运算符调用,则将该代码放在私有成员函数中,并从析构函数和赋值运算符调用该代码。

你的对象不会被破坏(你不希望它真的被破坏),但它会做与析构函数相同的事情。