正确使用类中的方法' = delete '

Correct use of `= delete` for methods in classes

本文关键字:delete 方法      更新时间:2023-10-16

下面的代码片段对于不定义所有其他生成的类方法和构造函数是正确的吗?

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

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

移动分配operator=(Picture&&)的返回类型Picture&是否正确?如果我为返回类型写Picture&&会有什么不同吗?

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

复制构造函数的显式声明禁止隐式生成默认构造函数、move构造函数和move赋值成员。是否显式删除这些成员取决于个人喜好。有些人可能会认为这是很好的文档。其他人可能会认为它过于啰嗦。

我觉得很好。operator= 的返回值必须是一个正常的引用,即使对象是从右值引用构造的。这是因为不能将左值(*this)编译为右值。
它应该为每个非const Picture& operator=(Picture&&)取右值引用。你如何从一个不变的物体移动?div;)