8

可能重复:
如何使用移动的对象?
什么构成 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;
  }

  ...
};
4

2 回答 2

6

The only thing you must be able to do with a moved-from object is destroy it. Beyond that, it's up to your class what the normal class invariants are and whether moved-from objects bother to satisfy them.

For example, it's a good idea to ensure that you can assign to the object, just in case someone wants to use std::move on an instance and give it a new value later. [Edit: as pointed out in an answer to one of the suggested-dupe questions, the general std::swap template moves from an object and then move-assigns to it, so if you don't ensure this then either you need to specialize std::swap or you need to forbid users of your class from using it.]

Since your class does nothing in its destructor, either option is fine. Option 2 might be easier for users to work with, but then again if they're coding on the assumption that they can't do anything with a moved-from object, then it makes no difference. Since the class is incomplete, though, that might change when you write the destructor.

于 2012-10-30T11:22:08.327 回答
6

已被移动的对象仍然是对象,并且它必须处于有效状态,尽管它可能是不确定的。特别是,应该可以安全地为其分配一个新值(当然它必须是可破坏的,正如@Steve 所说)。只要移出的对象保持有效,您就可以为自己的类赋予什么特定的语义。

通常,您应该将“移动”视为优化的“复制”。然而,对于一些本质上是“只移动”的类,例如unique_ptr,额外的保证可能是合适的——例如,unique_ptr承诺在它被移动之后它是空的,而且肯定没有其他东西真正有意义。

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

于 2012-10-30T11:29:27.740 回答