【问题标题】:Correct use of `= delete` for methods in classes对类中的方法正确使用 `= delete`
【发布时间】:2011-08-06 22:06:28
【问题描述】:

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

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 operator=(Picture&&) 的返回类型Picture& 是否正确?如果我为返回类型写 Picture&& 会有所不同吗?

【问题讨论】:

  • 在 C++0x 中,C++ 似乎真的发生了很大的变化!,有趣的东西。
  • 它的语法比将这些方法隐藏在private 部分中的常见做法更清晰,并且只声明而不是定义它们。

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


【解决方案1】:

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

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

【讨论】:

  • 谢谢,我在草稿中忽略了这一点。这样可以节省打字时间。如果我想让他们进来,我想我可以= default他们?
  • 是的。您可以显式默认它们或显式删除它们。
【解决方案2】:

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

【讨论】:

  • 当然,我真傻。你在这两个方面都是对的。让我在问题中纠正它,以免读者从我的错误示​​例中学习。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多