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

时间:2012-10-30 11:12:55

标签: c++ c++11 move-semantics

  

可能重复:
  How can moved objects be used?
  What constitutes a valid state for a “moved from” object in C++11?

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

e.g。在以下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;
  }

  ...
};

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:6)

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

一般来说,您应该将“移动”视为优化的“副本”。但是,对于某些本质上是“仅移动”的类,例如unique_ptr,其他保证可能是合适的 - 例如,unique_ptr承诺在移动之后 - 它是null,并且当然没有别的东西真的有意义。

(您的实际代码不完整,但鉴于FILE*是一种仅限移动的资源,它可能已被破坏,您应尽量模拟unique_ptr - 或者甚至use it directly。)