C++核心准则C.65:让移动操作对自赋值安全

网友投稿 618 2022-11-12

C++核心准则C.65:让移动操作对自赋值安全

C++核心准则C.65:让移动操作对自赋值安全

C.65: Make move assignment safe for self-assignment C.65:让移动操作对自赋值安全

Reason(原因)

If x = x changes the value of x, people will be surprised and bad errors may occur. However, people don't usually directly write a self-assignment that turn into a move, but it can occur. However, std::swap is implemented using move operations so if you accidentally do swap(a, b) where a and b refer to the same object, failing to handle self-move could be a serious and subtle error.

如果x=x改变了x的值,人们会感到诧异而且有可能发生严重的错误。虽然人们一般不会直接在移动操作中使用自赋值,它还是会发生。但是由于std::swap被实现为使用移动操作,如果你意外地调用了swap(a,b)而a和b参照了同一个对象,如果没有处理好自赋值的话,可能会发生严重且不易发现的错误。

Example(示例)

class Foo { string s; int i;public: Foo& operator=(Foo&& a); // ...};Foo& Foo::operator=(Foo&& a) noexcept // OK, but there is a cost{ if (this == &a) return *this; // this line is redundant s = std::move(a.s); i = a.i; return *this;}

The  one-in-a-million argument againstif (this == &a) return *this; tests from the discussion of self-assignment is even more relevant for self-move.

违反自我赋值检查的概率只有百万分之一(数据只要领会精神就好,译者注);避免自我赋值的讨论和自我移动的关系更加密切。

Note(注意)

There is no known general way of avoiding an if (this == &a) return *this; test for a move assignment and still get a correct answer (i.e., after x = x the value of x is unchanged).

没有避免使用if(this==&a)return *this;操作的普遍办法。检查移动赋值的方法仍然会得出正确的结果(例如在x=x之后x的值不会改变)。

Note(注意)

The ISO standard guarantees  only a "valid but unspecified" state for the standard-library containers. Apparently this has not been a problem in about 10 years of experimental and production use. Please contact the editors if you find a counter example. The rule here is more caution and insists on complete safety.

ISO标准只为标准库容易保证了一个“合法但未定义”的状态。看起来在10多年的经验和产品应用中没有成为问题。如果你遇到了反例请联系编辑。本规则更为谨慎并坚持做到完全安全。

Example(示例)

Here is a way to move a pointer without a test (imagine it as code in the implementation a move assignment):

这里有一个不检查就移动指针的方法(将其想象为实现移动赋值代码中的一部分):

// move from other.ptr to this->ptrT* temp = other.ptr;other.ptr = nullptr;delete ptr;ptr = temp;

译者注

如果other和this是同一个对象,other.ptr=nullptr也会同时将this.ptr置空,导致下面的delete ptr不起作用。这样就保证了自我移动时的安全。

这种做法太难理解了。

Enforcement(示例)

原文链接

​​https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c65-make-move-assignment-safe-for-self-assignment​​

觉得本文有帮助?欢迎点赞并分享给更多的人。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:log4j2采用AsyncLogger出现的错误及解决方案
下一篇:C++核心准则C.67:多态类应该抑制拷贝
相关文章

 发表评论

暂时没有评论,来抢沙发吧~