移动物体是否应保持"安全"状态?

Mr.*_*C64 8 c++ move-semantics c++11

可能重复:
如何使用移动的对象?
什么构成C++ 11中"移动"对象的有效状态?

在C++ 11中实现移动语义时,移动对象应该保持安全状态,还是只能处于"垃圾"状态?

例如,在以下C++ 11包装器示例中将原始FILE*资源实现移动构造函数的首选选项是什么?

// C++11 wrapper to raw FILE*
class File
{
  FILE* m_fp;

public:

  // Option #1
  File(File&& other)
    : m_fp(other.m_fp)
  {
    // "other" left in a "junk" state
  }

  // Option #2
  File(File&& other)
    : m_fp(other.m_fp)
  {
    // Avoid dangling reference in "other"
    other.m_fp = nullptr;
  }

  ...
};
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 6

必须能够使用移动对象做的唯一事情就是破坏它.除此之外,由您的类决定普通类不变量是什么以及是否从对象移动来满足它们.

例如,确保您可以分配给对象是个好主意,以防有人想要std::move在实例上使用并在以后为其提供新值.[编辑:正如在一个建议的欺骗问题的答案中所指出的,一般std::swap模板从一个对象移动然后移动 - 分配给它,所以如果你不确定这个,那么你需要专门化std::swap或者你需要禁止您的班级用户使用它.]

由于你的类在析构函数中什么都不做,所以两种选择都没问题.选项2对于用户来说可能更容易使用,但如果他们在假设他们无法对移动的对象做任何事情的情况下进行编码,那么它就没有区别.但是,由于类不完整,因此在编写析构函数时可能会发生变化.


Ker*_* SB 6

已移动的对象仍然是对象,它必须处于有效状态,尽管它可能是不确定的.特别是,应该可以安全地为它分配一个新值(当然它必须是可破坏的,正如@Steve所说).只要移动的对象仍然有效,这取决于您希望为您的类提供什么特定的语义.

一般来说,您应该将"移动"视为优化的"副本".但是,对于某些本质上是"仅移动"的类,例如unique_ptr,额外的保证可能是合适的 - 例如,unique_ptr在它被移动之后的承诺是空的,并且肯定没有其他任何真正有意义的.

(你的实际代码是不完整的,但鉴于a FILE*是一种只移动资源,它可能已被破坏,你应该尝试尽可能地模拟unique_ptr- 甚至直接使用它.)