app开发者平台在数字化时代的重要性与发展趋势解析
608
2022-11-12
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~