我在另一个问题中读到,在实现移动构造函数时,最好将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(很差)但是如果成员是对象我感兴趣.
阅读链接的问题后,我可以看到第二个最受欢迎的答案中的建议是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)
上述移动赋值运算符和您的移动赋值运算符之间的区别在于,内存的释放会被延迟,而您的版本会立即释放内存,这在某些情况下可能很重要。