8

我发生了一些事情,我认为这是完全合理的,但我希望人们对此发表意见,以防我完全错过了一些东西。所以首先,我的理解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不一定是空的!那么,为什么不做一个 plainswap呢?

T& operator=(T&& rhs) {
    rhs.swap(*this); // is this good enough?
    return *this;
}

认为这满足了移动分配操作员需要做的事情......但就像我说的,这只是发生在我身上,所以我认为我可能遗漏了一些东西。

我能想到的唯一“缺点”是,this与执行移动构造/交换的版本相比,使用普通交换拥有的东西可能会活得更长。

想法?

4

1 回答 1

7

“移动赋值运算符需要做什么”

我总是发现处理&&变量的最佳方法是说“没有人关心我将这个变量留在什么状态”。你可以离开它。您可以从中复制。你可以换成它。你可以做的事情还有很多。

你的代码是正确的。&&可以保持任何状态(只要它是可破坏的)。

对象迟早会被销毁(可能更早),实现者应该意识到这一点。如果析构函数将使用delete原始指针,这一点很重要,如果相同的原始指针位于多个对象中,这将导致双重删除。

于 2015-08-26T19:27:33.297 回答