重置对象
Reset an object
最近我经常通过 operator=
为它分配一个新值来重置一个对象。我的大多数 类 都有一个 copy constructor
和 operator=
使用 "copy and swap" 习语定义。在大多数情况下,它工作得很好,尽管效率不高,但这在大多数情况下并不重要。有一种情况是这不起作用。它是在 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 Whosebug 让我不这么认为。
我真的很喜欢 operator= 来重置我的对象,因为代码很干净并且与内置类型(如 int)相同。它还使用了 constructor
和 destructor
中的代码,因此无需编写和维护额外的代码。
所以我的问题是:有没有一种方法可以实现我的目标,即使用干净的代码重置我的对象,无需编写额外的代码,并在构造新对象之前销毁该对象?
如果构造函数中的代码也需要由赋值运算符调用,则将该代码放在私有成员函数中,并从析构函数和赋值运算符中调用它。
您的对象不会被析构(您不希望它真的被析构),但它会做与析构函数相同的事情。
根据定义,如果您向旧对象分配新值,则新值在分配发生之前已经构造好。
你的'old object'也没有真正被破坏。
所以不行,没办法。而且不应该:您不应该重新定义赋值运算符的 'obvious' 行为。
但是除了波浪号和异国情调的构造语法之外,placement new 在这里可能有所帮助,也许这段代码接近 'clean' :)
Foo old(a, b, c);
old.~Foo(); // explicit destruction
new (&old) Foo(d, e, f);
最近我经常通过 operator=
为它分配一个新值来重置一个对象。我的大多数 类 都有一个 copy constructor
和 operator=
使用 "copy and swap" 习语定义。在大多数情况下,它工作得很好,尽管效率不高,但这在大多数情况下并不重要。有一种情况是这不起作用。它是在 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 Whosebug 让我不这么认为。
我真的很喜欢 operator= 来重置我的对象,因为代码很干净并且与内置类型(如 int)相同。它还使用了 constructor
和 destructor
中的代码,因此无需编写和维护额外的代码。
所以我的问题是:有没有一种方法可以实现我的目标,即使用干净的代码重置我的对象,无需编写额外的代码,并在构造新对象之前销毁该对象?
如果构造函数中的代码也需要由赋值运算符调用,则将该代码放在私有成员函数中,并从析构函数和赋值运算符中调用它。
您的对象不会被析构(您不希望它真的被析构),但它会做与析构函数相同的事情。
根据定义,如果您向旧对象分配新值,则新值在分配发生之前已经构造好。
你的'old object'也没有真正被破坏。
所以不行,没办法。而且不应该:您不应该重新定义赋值运算符的 'obvious' 行为。
但是除了波浪号和异国情调的构造语法之外,placement new 在这里可能有所帮助,也许这段代码接近 'clean' :)
Foo old(a, b, c);
old.~Foo(); // explicit destruction
new (&old) Foo(d, e, f);