在为类实现移动分配运算符时是否真的需要进行自赋值检查?

时间:2018-12-02 10:35:31

标签: c++ c++11 move-semantics move-assignment-operator

Type &Type::operator=(Type &&rhs)
{
if(this == &rhs) //is there any need of self-assignment . 
returh *this ;
}
...
}

//因为它将在r值上调用,所以为什么要进行自赋值??

1 个答案:

答案 0 :(得分:2)

通常...

假设您的类拥有一个指向其分配的缓冲区的指针。现在,在一个简单的移动分配运算符中,您将:

  • 释放自己的缓冲区
  • 将另一个对象的缓冲区指针分配给您的缓冲区指针
  • 将null分配给另一个对象的缓冲区指针,并可能将其大小设置为0

这不会使您取消引用空指针,但是-您刚刚丢失了缓冲区中的所有数据,这可能不是您想要的,也不是用户期望的。

...但并非总是如此

上面的规则有一个(狭义)例外:您的移动分配运算符对于自赋值是“幂等”的情况。例如,如果您的赋值运算符仅涉及成员的赋值-那么就像常规赋值一样进行自赋值是安全的(信任成员的自赋值实现是有效的)。什么都不会改变或丢失。

该规则的例外确实很狭窄,因为在我给出的示例中,上述内容基本上是正确的-在这种情况下,您将使用默认的move-assignment运算符。尽管如此,仅仅因为您在某人的代码中找不到该检查并不意味着存在错误。