【发布时间】:2019-01-15 09:18:11
【问题描述】:
考虑以下sn-p:
class Foo
{
public:
/* ... */
Foo(Foo &&other);
~Foo();
Foo &operator=(Foo &&rhs);
private:
int *data;
};
Foo::Foo(Foo &&other)
{
data = other.data;
other.data = nullptr;
}
Foo::~Foo()
{
delete data;
}
Foo &Foo::operator=(Foo &&other)
{
if (this == &other) return *this;
delete data; /* SAME AS DESTRUCTOR */
data = other.data; /* SAME AS MOVE CONSTRUCTOR */
other.data = nullptr;
return *this;
}
这个 sn-p 几乎就是我最终拥有的东西。
如果可以推断出它的行为,为什么我们需要一个移动运算符?
如果此语句不正确,在这种情况下,移动运算符的行为与析构函数 + 移动构造函数的行为不同?
【问题讨论】:
-
例如可以写成
::std::swap(this->data, other.data) -
尽管这只是一个示例,但您应该将初始化列表与构造函数一起使用,并且您的赋值函数在所有情况下都不会返回结果。执行
this != &other比您拥有的逻辑更可取,然后始终返回 *this。 -
Howard Hinnant 的这个答案给出了一个相关的讨论,说明为什么可能没有 single best version 的移动赋值运算符:stackoverflow.com/a/9322542/580083。另一个:stackoverflow.com/a/39864881/580083.
-
复制交换习语基本上就是这样做的