最近,我经常通过operator=
为其指定一个新值来重置对象。我的大多数课程都使用“复制和交换”习惯来定义copy constructor
和operator=
。在大多数情况下,哪种方法效果不错,尽管效率不高,但大多数情况并不重要。有一种情况虽然这不起作用。当需要在新对象的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引用执行) 。但是this answer on stackOverflow让我想到了。
我非常喜欢operator =来重置我的对象,因为代码是干净的,并且与内置类型(如int)相同。它还使用constructor
和destructor
中的代码,因此不需要编写和维护额外的代码。
所以我的问题是:有没有办法实现我的目标,用干净的代码重置我的对象,不需要编写额外的代码,并在构造新对象之前破坏对象?
答案 0 :(得分:1)
如果构造函数中的代码也需要由赋值运算符调用,则将该代码放在私有成员函数中,并从析构函数和赋值运算符中调用它。
您的对象不会被破坏(并且您不希望它真的被破坏),但它将与析构函数做同样的事情。
答案 1 :(得分:1)
根据定义,如果为旧对象分配一个新值,则在赋值发生之前已经构造了新值。
你的“老物件”也没有被破坏。
所以没有。没有办法。并且不应该:你不应该重新定义赋值运算符的“明显”行为。
但是除了波浪形和异国情调的构造语法之外,新的位置可能有所帮助,也许这个代码接近'干净':)
Foo old(a, b, c);
old.~Foo(); // explicit destruction
new (&old) Foo(d, e, f);