30 October 2022

C++ 核心指南目录

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;除非有很强烈的特殊理由违反本指南。

强化

  • 检查对成员赋值的移动操作。如果有默认的构造函数,请比较成员赋值与默认构造函数中的初始化。