31

对于取消定义类的所有其他生成的方法和构造函数,以下片段是否正确?

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?
};

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

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

4

2 回答 2

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;
};

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

于 2011-04-16T15:32:16.073 回答
3

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

于 2011-04-16T14:23:24.000 回答