std :: move里面的移动赋值运算符

Tom*_*P89 6 c++ move c++11

我在另一个问题中读到,在实现移动构造函数时,最好将std :: move移动到初始化列表中,因为如果该成员碰巧是另一个对象,那么将调用该对象移动构造函数.像这样......

//Move constructor
Car::Car(Car && obj)
    : 
    prBufferLength(std::move(obj.prBufferLength)), 
    prBuffer(std::move(obj.prBuffer)) 
{
    obj.prBuffer = nullptr;
    obj.prBufferLength = 0;
}
Run Code Online (Sandbox Code Playgroud)

但是在我看过的所有示例移动赋值运算符中,没有提到使用std :: move的原因相同.如果成员是一个对象,那么应该使用std :: move吗?像这样......

//Move assignment
Car Car::operator=(Car && obj)  
{
    delete[] prBuffer;

    prBufferLength = std::move(obj.prBufferLength);
    prBuffer = std::move(obj.prBuffer);

    obj.prBuffer = nullptr;
    obj.prBufferLength = 0;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

更新:

我很欣赏没有必要在我选择的例子中使用std :: move(很差)但是如果成员是对象我感兴趣.

Jes*_*ood 3

阅读链接的问题后,我可以看到第二个最受欢迎的答案中的建议是std::move在移动构造函数的初始值设定项列表中使用,因为无论它是否是原始类型,它都会做正确的事情。我有点不同意这一点,并认为你应该只std::move在适当的时候打电话,但这是个人喜好的影响。

另外,对于您的移动赋值运算符,您的方式很好,尽管我认为std::move应该亲自删除不必要的调用。另一种选择是使用std::swap哪个会为您做正确的事情。

Car Car::operator=(Car && obj)  
{
    std::swap(this->prBufferLength, obj.prBufferLength);
    std::swap(this->prBuffer, obj.prBuffer); 
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

上述移动赋值运算符和您的移动赋值运算符之间的区别在于,内存的释放会被延迟,而您的版本会立即释放内存,这在某些情况下可能很重要。