使类不可复制*和*不可移动

时间:2015-10-13 07:30:18

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

在C ++ 11之前,我可以使用它来使类不可复制:

private:
MyClass(const MyClass&);
MyClass& operator=(const MyClass&);

使用C ++ 11,我可以这样做:

MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;

当使用具有已删除副本和赋值的类时,是否有可能生成默认移动运算符?而且这个类并没有被完全复制,而是移动了(这有点类似)?

那么,我是否必须这样做以防止默认移动构造和assignmnent:

MyClass(MyClass&&) = delete;
MyClass& operator=(MyClass&&) = delete;

......?

2 个答案:

答案 0 :(得分:20)

正如评论中已经提到的其他人一样,删除的构造函数是在C ++ 11中引入的。要回答您的问题,通常会遵循以下规则:

  1. 两个复制操作是独立的。声明复制构造函数不会阻止编译器生成复制分配,反之亦然。 (与C ++ 98相同)
  2. 移动操作不是独立的。声明其中任何一个都会阻止编译器生成另一个。 (与复制操作不同。)
  3. 如果声明了任何复制操作,则不会生成任何移动操作。 (您的情况。)
  4. 如果声明了任何移动操作,则不会生成任何复制操作。这是前一条规则的相反规则。
  5. 如果声明了析构函数,则不会生成任何移动操作。仍然生成复制操作以与C ++ 98反向兼容。
  6. 仅在未声明构造函数时生成默认构造函数。 (与C ++ 98相同)
  7. 根据评论中的要求,这里有一些来源(C ++ 11是草案N3242):

    • 复制操作:§12.8.8,§12.8.19
    • 移动操作:§12.8.10,§12.8.21
    • 默认构造函数:§12.1.5

答案 1 :(得分:11)

声明复制构造函数时,不会生成移动构造函数/赋值。

所以

MyClass(MyClass&&) = delete;
MyClass& operator=(MyClass&&) = delete;

不是必需的。

您仍然可以将其添加为更明确。