CppCoreGuidelines C.64 移动操作应该移动,并确保留下的数据状态有效
30 October 2022
C.64: A move operation should move and leave its source in a valid state
理由
在y = std::move(x)
操作后, y
的值应该变成 x
的值, x
应该保持一个有效的状态。
例子
class X { // OK: value semantics public: X(); X(X&& a) noexcept; // move X X& operator=(X&& a) noexcept; // move-assign X void modify(); // change the value of X // ... ~X() { delete[] p; } private: T* p; int sz; }; X::X(X&& a) noexcept :p{a.p}, sz{a.sz} // steal representation { a.p = nullptr; // set to "empty" a.sz = 0; } void use() { X x{}; // ... X y = std::move(x); x = X{}; // OK } // OK: x can be destroyed
注意
理想情况下,被移动掉数据的对象,它的值应该是默认数据值。如果你不想这样,你得有一个充足的理由。但是,并不是所有类型都有一个默认值,而且有些类型恢复默认值的系统开销会比较高。所以,标准只要求销毁掉被移动的对象。通常,我们可以很容易很轻松的做的更好:标准库还假设,我们可以继续给被移动掉的对象赋值。请确保,被移动掉的对象保持一个有效的状态。
注意
请确保这么操作是合法的:x = std::move(y); y = z;
除非有很强烈的特殊理由违反本指南。
强化
- 检查对成员赋值的移动操作。如果有默认的构造函数,请比较成员赋值与默认构造函数中的初始化。