对类中的方法正确使用`= delete`

时间:2011-04-16 14:12:11

标签: c++ c++11 operator-overloading move-semantics rvalue-reference

以下snipplet是否正确用于取消定义类的所有其他方法和构造函数?

struct Picture {

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no accidental construction, i.e. temporaries and the like
  Picture() = delete;

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;

  // no move
  Picture(Picture&&) = delete;

  // no move-assign
  Picture& operator=(Picture&&) = delete; // return type correct?
};

这会删除每个默认的编译器实现,只留下析构函数,对吧?没有它,我猜这个类(几乎)无法使用,但我也可以删除它,对吗?

move-assign Picture&的返回类型operator=(Picture&&)是否正确?如果我为返回类型写了Picture&&,它会有所作为吗?

2 个答案:

答案 0 :(得分:27)

除了Xeo的回答:

是的,一切都是正确的。如果您希望删除所有已删除的成员,但删除的复制构造函数和已删除的副本分配具有相同的效果:

struct Picture {  // Also ok

  // 'explicit': no accidental cast from string to Picture
  explicit Picture(const string &filename) { /* load image from file */ }

  // no copy
  Picture(const Picture&) = delete;

  // no assign
  Picture& operator=(const Picture&) = delete;
};

复制构造函数的显式声明禁止隐式生成默认构造函数,移动构造函数和移动赋值成员。明确删除这些成员是一个品味问题。有些人可能会将其视为良好的文档。其他人可能会认为它过于冗长。

答案 1 :(得分:3)

对我来说似乎很好。 operator= 的返回值必须是正常引用,即使该对象是由右值引用构造的。那是因为你不能只将左值(*this)编译成右值 它应该采用每个非const Picture& operator=(Picture&&)的rvalue引用。你将如何从一个恒定的物体移动? ;)