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

Jan*_*egg 13 c++ constructor move move-semantics c++11

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

private:
MyClass(const MyClass&);
MyClass& operator=(const MyClass&);
Run Code Online (Sandbox Code Playgroud)

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

MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
Run Code Online (Sandbox Code Playgroud)

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

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

MyClass(MyClass&&) = delete;
MyClass& operator=(MyClass&&) = delete;
Run Code Online (Sandbox Code Playgroud)

......?

mcs*_*rep 21

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

  1. 这两个复制操作是独立的.声明复制构造函数不会阻止编译器生成复制分配,反之亦然.(与C++ 98相同)
  2. 移动操作不是独立的.声明其中任何一个都会阻止编译器生成另一个.(与复制操作不同.)
  3. 如果声明了任何复制操作,则不会生成任何移动操作. (你的情况.)
  4. 如果声明了任何移动操作,则不会生成任何复制操作.这是前一个相反的规则.
  5. 如果声明了析构函数,则不会生成任何移动操作.仍然生成复制操作以与C++ 98反向兼容.
  6. 仅在未声明构造函数时生成默认构造函数.(与C++ 98相同)

根据评论中的要求,这里有一些来源(C++ 11是草案N3242):

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

  • 这是我的知识:)为了您的要求,我扩展了我的答案,并添加了一些C++标准的引用来支持它. (3认同)
  • 你从哪里得到这些事实? (2认同)

Jar*_*d42 12

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

所以

MyClass(MyClass&&) = delete;
MyClass& operator=(MyClass&&) = delete;
Run Code Online (Sandbox Code Playgroud)

不是必需的.

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

  • 明确是好的:我总是声明所有的操作符,并有选择地“删除”我不需要的操作符。它使我的意图清晰,万一有编译器错误,它仍然应该按我期望的方式工作。 (3认同)