默认移动构造函数/赋值和删除的复制构造函数/赋值

2024-04-19

根据标准,

如果类 X 的定义没有显式声明移动构造函数,则当且仅当

— X 没有用户声明的复制构造函数,

— X 没有用户声明的复制赋值运算符,

— X 没有用户声明的移动赋值运算符,并且

— X 没有用户声明的析构函数。

现在以下无法编译

# include <utility>

class Foo
{
public:
  Foo() = default;
  Foo(Foo const &) = delete;
};

int main()
{
  Foo f;
  Foo g(std::move(f)); // compilation fails here
  return 0;
}

因此,删除的函数似乎被视为用户定义的,这是有道理的(这不是它的默认实现)。但是,在这种特殊情况下,删除的复制构造函数/赋值会如何混乱默认移动构造函数/赋值?

我认为这个问题具有实际重要性,因为手动生成和特别是。维护这样的默认函数很容易出错,同时,(正义的)增加类的使用,例如std::unique_ptr因为类成员使得不可复制的类比以前更加常见。


user-declared意味着要么用户提供的 (defined由用户),明确默认 (= default) or 明确删除 (= delete)与隐式默认/删除(例如您的移动构造函数)相反。

所以就你而言,yes移动构造函数是隐含地已删除,因为复制构造函数是明确地已删除(因此用户声明的).

但是,在这种特殊情况下,删除的复制构造函数/赋值会如何混乱默认移动构造函数/赋值?

不会,但标准并不能区分这种情况和复杂的情况。

最短的答案是,有一个隐含地定义的移动构造函数明确地删除的复制构造函数might在某些情况下是危险的,当你有一个用户自定义析构函数和没有用户自定义复制构造函数(参见三/五/零规则 http://en.cppreference.com/w/cpp/language/rule_of_three)。现在,您可以认为用户定义的析构函数不会删除复制构造函数,但这只是一个flaw使用无法删除的语言,因为它会破坏许多旧的(坏的)程序。引用 Bjarne Stroustrup 的话:

在理想的世界中,我认为我们会决定“不生成”作为默认值,并为“给我所有常规操作”提供一个非常简单的符号。 [...]此外,“无默认操作”策略会导致编译时错误(我们应该有一个简单的方法来修复),而默认生成操作策略会导致运行时之前无法检测到的问题。

您可以阅读有关此内容的更多信息N3174=10-0164 http://www.stroustrup.com/move.pdf.

请注意,大多数人都遵循三/五/零规则 http://en.cppreference.com/w/cpp/language/rule_of_three,我认为你应该这样做。通过隐式删除默认的移动构造函数,该标准可以“保护”您免受错误的影响,并且应该在很长一段时间内通过在某些情况下删除复制构造函数来保护您(请参阅 Bjarne 的论文)。

如果您有兴趣,请进一步阅读:

  • 执行零规则 http://accu.org/index.php/journals/1896
  • N3153 - 隐式移动必须进行 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3153.htm
  • N3174 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3174.pdf
  • N3201 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3201.pdf

我认为这个问题具有实际重要性,因为手动生成和特别是。维护这样的默认函数很容易出错,同时,(正义的)增加类的使用,例如std::unique_ptr因为类成员使得不可复制的类比以前更加常见。

将移动构造函数标记为显式默认将解决此问题:

class Foo {
public:
  Foo() = default;
  Foo(Foo const &) = delete;
  Foo(Foo&&) = default;
};

您将获得一个带有默认移动构造函数的不可复制对象,在我看来,这些显式声明比隐式声明更好(例如,仅将移动构造函数声明为default不删除复制构造函数)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

默认移动构造函数/赋值和删除的复制构造函数/赋值 的相关文章

随机推荐

  • Windows 中 CMake 的默认生成器是什么?

    在一台 PC 上运行 CMake 时 CMake 默认生成 NMake 文件 另一方面 它生成一个 Visual Studio 项目 我知道我可以通过添加来覆盖默认值 G NMake Makefiles 到我的 CMake 语句的末尾 但我
  • android autocompletetextview 应仅在下拉列表中显示相关选项

    我在代码中使用 AutoCompleteTextView 并使用 SimpleCursorAdapter 从数据库加载列表 AutoCompleteTextView cocktailIngredientView AutoCompleteTe
  • 应用程序更新时的 NSUserDefaults 行为

    我的 iOS 应用程序中有一个方法 可以在检测到我的服务器具有适用于我的应用程序的更高版本 新的 ipa 版本 时更新应用程序 如果用户想要下载它 该应用程序会在 iPad 上自行更新 问题是 当应用程序第一次打开新版本时 我想更新数据库中
  • Amazon Elastic Beanstalk npm 找不到 package.json

    我对亚马逊网络服务非常陌生 我正在尝试在他们的弹性beanstalk上设置一个node js应用程序 我设置了实例并上传 部署了站点 但是虽然运行状况 正常 但 node js 日志显示此情况重复了大约 30 次 npm ERR enoen
  • 如何使用 Netty 发送对象?

    如何通过Netty从服务器端发送bean并在客户端接收该bean 当我发送简单的整数消息 inputstream 时 它工作成功 但我需要发送 bean 如果您在客户端和服务器端使用 Netty 那么您可以使用 Netty对象解码器 htt
  • 以编程方式关闭 WP7 应用程序? [复制]

    这个问题在这里已经有答案了 可能的重复 Windows Phone 7 关闭应用程序 https stackoverflow com questions 3659195 windows phone 7 close application 如
  • 表达忽略视图目录

    我已经设置了一个配置文件来存储我的 Express 应用程序的应用程序路径 cookie 秘密等设置 问题是它似乎忽略了我的视图路径目录设置 配置 js exports server port 3000 cookie secret path
  • 使用类的 __new__ 方法作为工厂:__init__ 被调用两次

    我在 python 中遇到了一个奇怪的错误 其中使用 new 将类的方法作为工厂会导致 init 实例化类的方法被调用两次 这个想法最初是为了使用 new 母类的方法根据传递的参数返回其子类之一的特定实例 而无需在类外部声明工厂函数 我知道
  • 需要类或命名空间;语法正确且正确

    在 dualstk h 中 ifndef 32 dualstk h define 32 dualstk h include
  • AWS 检查状态机/Step Functions 并发运行

    我在处理状态机 步骤函数 的并发运行时遇到很多问题 该状态机中确实有胶水作业任务 状态机由 Lambda 启动 并由 FIFO SQS 队列触发 lambda 获取消息 检查正在运行的状态机实例数量 如果该数量低于 GlueJob 并发运行
  • .htaccess 将一个文件夹中的所有文件重定向到另一个文件夹中的完全相同的文件

    我们只需将名为 音乐 的目录中的每个页面移动到名为 信息 的目录 这是唯一的更改 有很多指向音乐页面的链接 我们不想全部破坏 我不擅长重写条件 基本上 我想做的就是当用户输入 music index php 或 music life myp
  • 复合属性

    有没有办法在 C 中制作复合属性以在编译时提供等效的元数据 例如 改变 ClassInterface ClassInterfaceType AutoDual ProgId MyProgId MyMefExport MyProgId publ
  • 有没有办法使用 getUserMedia 减少延迟?

    在尝试减少视频延迟的同时WebRTC通信时 我测量了视频捕获和视频显示之间的延迟 为了防止测量 WebRTC 涉及的延迟 我只是使用getUserMedia和一个 HTMLvideo显示流 我通过每帧显示时间戳来做到这一点 使用reques
  • 编译器错误:对调用的引用不明确

    Case 1 static void call Integer i System out println hi i static void call int i System out println hello i public stati
  • 更改 ToolStripMenuItem 的大小

    我正在自定义绘制一个菜单项MenuStrip 我遇到的问题是菜单项坚持根据文本调整自身大小 这不是我想要的 没有文本 我可以设置AutoSize设置为 false 并显式指定大小 但包含的菜单 ToolStripDropDown 仍然根据文
  • $_POST、$_GET 和 $_REQUEST 为空

    SOLVED 我省略了输入字段中的名称属性 我有一个简单的 html php 表单 我提交了 POST 始终为空 如果我尝试 get 那么 GET 总是空的 REQUEST 和 php input 相同 我没有得到任何回报 有很多关于这个主
  • AVCaptureVideoPreviewLayer 和从相机位置预览

    我正在开发一个允许用户拍照的应用程序 我已经开始使用AVCam https developer apple com library ios samplecode AVCam Introduction Intro html苹果提供了 但我实际
  • ElasticSearch - 索引模板和索引模式有什么区别

    我在这里阅读了对我的问题的解释 https discuss elastic co t whats the differece Between index pattern and index template 54948 https disc
  • 如何通过 django admin 中的操作请求用户输入?

    在我的代码中 我正在编写一个分组操作 我想询问用户每个组需要多少人 然后用一个警报框进行响应 根据用户输入显示 您有 4 个组 的内容 我如何在 django admin 中执行此操作 如何创建某种弹出窗口来询问他们想要放入一个组中的人数
  • 默认移动构造函数/赋值和删除的复制构造函数/赋值

    根据标准 如果类 X 的定义没有显式声明移动构造函数 则当且仅当 X 没有用户声明的复制构造函数 X 没有用户声明的复制赋值运算符 X 没有用户声明的移动赋值运算符 并且 X 没有用户声明的析构函数 现在以下无法编译 include