使用 swap 实现移动赋值
using swap to implement move assignment
我想到了一些我认为完全合理的事情,但我希望人们对此发表意见,以防我完全遗漏某些东西。所以首先,我对 T& operator=(T&& rhs)
的理解是我们 不关心 当我们完成后 rhs
的内容是什么,只是内容已被移动进入 this
并且 rhs
是可安全破坏的。
也就是说,复制赋值运算符的常见异常安全实现,假设交换很便宜,看起来像这样:
T& operator=(const T& rhs) {
if(this != &rhs) {
T(rhs).swap(*this);
}
return *this;
}
因此,实现移动赋值运算符的一种自然方式如下:
T& operator=(T&& rhs) {
if(this != &rhs) {
T(std::move(rhs)).swap(*this);
}
return *this;
}
但后来我想到,rhs
不一定是空的!那么,为什么不直接做一个简单的 swap
?
T& operator=(T&& rhs) {
rhs.swap(*this); // is this good enough?
return *this;
}
我认为这满足了移动赋值运算符需要做的...但是就像我说的,这只是我想到的,所以我认为有可能我错过了一些东西。
我唯一能想到的 "downside" 是 this
拥有的东西与使用 move-construct/swap 的版本相比,使用普通交换可能会活得更久。
想法?
"what the move-assignment operator needs to do"
我总是发现处理 &&
变量的最佳方法是说 "nobody cares what state I leave this variable in"。你可以离开它。您可以从中复制。您可以换成它。您可以做更多的事情。
您的代码是正确的。 &&
可以保持任何状态(只要它是可破坏的)。
对象迟早会被销毁(可能更早),实现者应该意识到这一点。如果析构函数将 delete
原始指针,这很重要,如果同一个原始指针在多个对象中,这将导致双重删除。
我想到了一些我认为完全合理的事情,但我希望人们对此发表意见,以防我完全遗漏某些东西。所以首先,我对 T& operator=(T&& rhs)
的理解是我们 不关心 当我们完成后 rhs
的内容是什么,只是内容已被移动进入 this
并且 rhs
是可安全破坏的。
也就是说,复制赋值运算符的常见异常安全实现,假设交换很便宜,看起来像这样:
T& operator=(const T& rhs) {
if(this != &rhs) {
T(rhs).swap(*this);
}
return *this;
}
因此,实现移动赋值运算符的一种自然方式如下:
T& operator=(T&& rhs) {
if(this != &rhs) {
T(std::move(rhs)).swap(*this);
}
return *this;
}
但后来我想到,rhs
不一定是空的!那么,为什么不直接做一个简单的 swap
?
T& operator=(T&& rhs) {
rhs.swap(*this); // is this good enough?
return *this;
}
我认为这满足了移动赋值运算符需要做的...但是就像我说的,这只是我想到的,所以我认为有可能我错过了一些东西。
我唯一能想到的 "downside" 是 this
拥有的东西与使用 move-construct/swap 的版本相比,使用普通交换可能会活得更久。
想法?
"what the move-assignment operator needs to do"
我总是发现处理 &&
变量的最佳方法是说 "nobody cares what state I leave this variable in"。你可以离开它。您可以从中复制。您可以换成它。您可以做更多的事情。
您的代码是正确的。 &&
可以保持任何状态(只要它是可破坏的)。
对象迟早会被销毁(可能更早),实现者应该意识到这一点。如果析构函数将 delete
原始指针,这很重要,如果同一个原始指针在多个对象中,这将导致双重删除。