复制构造函数和移动构造函数的效率差异

2024-05-06

C++11引入了右值引用的新概念。我在某处读到它并发现以下内容:

class Base
{
public:
    Base()  //Default Ctor
    Base(int t)  //Parameterized Ctor

    Base(const Base& b)  //Copy Ctor
    Base(Base&& b)  //Move Ctor
};

void foo(Base b)     //Function 1
{}

void foo(Base& b)   //Function 2
{}

int main()
{
    Base b(10);
    foo(b);        -- Line 1 (i know of ambiquity but lets ignore for understanding purpose)
    foo(Base());   -- Line 2
    foo(2) ;       -- Line 3
}

现以我有限的理解,我的观察如下:

  1. 第 1 行将简单地调用复制构造函数,因为参数是左值。

  2. C++11 之前的第 2 行将调用复制构造函数和所有那些临时复制内容,但定义了移动构造函数后,将在此处调用它们。

  3. 第 3 行将再次调用移动构造函数,因为第 2 行将隐式转换为基本类型(右值)。

以上观察如有错误,请指正并解释。

现在,这是我的问题:

  1. 我知道一旦我们移动一个对象,它的数据就会在调用位置丢失。那么,在上面的示例中,我如何更改第 2 行以移动 foo 中的对象“b”(是否使用 std::move(b) ?)。

  2. 我读过移动构造函数比复制构造函数更有效。如何?我能想到的唯一情况是,在移动构造函数的情况下,堆上有内存不需要再次分配。当我们堆上没有任何内存时,这个说法是否成立?

  3. 它比通过引用传递更有效吗(不,对吧?)?


首先谈谈你的“理解”:

据我所知,他们原则上是正确的,但你应该意识到复制省略 https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization这可能会阻止程序调用任何复制/移动构造函数。取决于您的编译器(-设置)。

关于您的问题:

  1. 是的,您必须调用 foo(std::move(b)) 来调用带有左值的右值的函数。 std::move 将进行转换。注意: std::move 本身并不移动任何东西 https://stackoverflow.com/questions/21358432/why-is-stdmove-named-stdmove.

  2. 使用移动构造函数“可能”更有效。事实上,它只能让程序员实现一些更高效的构造函数。示例考虑一个向量,它是一个围绕指向保存数据的数组的指针的类(类似于 std::vector),如果复制它,则必须复制数据,如果移动它,则只需传递指针并设置旧的为 nullptr。 但当我读到有效的现代 C++ https://www.amazon.de/Effective-Modern-Specific-Ways-Improve/dp/1491903996作者:Scott Meyers:不要认为你的程序会更快,只是因为你使用了 std::move everywere。

  3. That depends on the usage of the input. If you do not need a copy in the function it will in the most cases be more efficient to just pass the object by (const) reference. If you need a copy there are several ways of doing it for example the copy and swap idiom https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom. But as a

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

复制构造函数和移动构造函数的效率差异 的相关文章

  • 异步回调到BackgroundWorker

    我想使用 NET FTP 库 http netftp codeplex com http netftp codeplex com 该库提供 BeginOpenRead string AsyncCallback object 使用异步编程模型
  • VS Code:自定义关键字的注入语法范围在 C++ 中被覆盖

    我想制作一个小型 VS Code 扩展 为 C C 代码中的少数自定义关键字添加语法突出显示 我正在尝试通过注入语法来做到这一点source c and source cpp语言范围 遵循VS Code 语法高亮指南 https code
  • do { ... } while (0) — 它有什么用? [复制]

    这个问题在这里已经有答案了 我已经看到这个表情十多年了 我一直在努力思考它有什么好处 因为我主要在 defines 中看到它 所以我认为它对于内部作用域变量声明和使用中断 而不是 gotos 很有用 对其他方面有好处吗 你用它吗 这是 C
  • 无捕获 lambda 是结构类型吗?

    P1907R1 http www open std org jtc1 sc22 wg21 docs papers 2019 p1907r1 html 接受 C 20 引入结构类型 它们是非类型模板参数的有效类型 GCC 和 Clang 都接
  • 将 LUIS 与 FormFlow 集成

    我创建了一个机器人 里面有一个 FormFlow 现在 如果您输入 我想启动产品 LUIS 将告诉它必须转到哪个对话框 internal static IDialog
  • 未定义的参考错误 - rand

    我正在创建一个命令行 C 测试应用程序 可执行 以便在我的 root Android 设备上运行 该可执行文件使用多个预构建的 C 库 其中之一使用 rand 在链接状态期间我收到错误 rand 的未定义引用 为了检查路径是否设置正确 我尝
  • 如何从 C# 可移植类库 (PCL) 添加对 F# 可移植库的引用

    我有一个项目 其中包含两个 F 项目和一个 C 项目 我想在其中编写一些 XUnit 测试 FS PL F 3 1 3 3 1 0 可移植库 FS PL Legacy F 31 2 3 5 1 可移植库 旧版 测试 C NET 4 5 Wi
  • unique_ptr需要存储删除器怎么可能没有开销呢?

    先看看C Primer讲了什么unique ptr and shared ptr 16 1 6 美元 效率和灵活性 我们可以确定的是shared ptr不将删除者视为直接成员 因为删除器的类型直到运行时才知道 因为删除器的类型是a类型的一部
  • 关闭模态后清除模态字段

    我有这个模式
  • 安全地检查“this”是否为空

    首先 我知道在空指针上调用方法是未定义的行为 我还知道 因为这不应该发生 编译器可以 并且确实 假设this始终为非空 但在实际代码中 有时您会不小心这样做 通常 它没有任何不良影响 当然除了this方法中为 null 并且事情可能会崩溃
  • GridView必须添加到表单标签中才能渲染

    TextWriter tr new StringWriter HtmlTextWriter writer new HtmlTextWriter tr HtmlForm form new HtmlForm form Controls Add
  • 大表的最佳主键格式

    我正在开发一个 ASP NET 应用程序 它有一些可能很大的数据表 我想知道定义主键的最佳方法是什么 我知道以前已经有人问过这个问题 但由于这是针对特定情况的 所以我认为这个问题是有效的 我在 SQL Server 2008 数据库上使用实
  • 我如何错误地使用 C 中的 round() 函数?

    我从中得到了意想不到的结果round and roundf 中的函数math h图书馆 这是示例代码 include
  • 如何在调试时轻松查看事件订阅数量?

    在调试时 我可以查看一下textBox1 TextChanged查看事件订阅数量 如果是 那么我该如何钻取它 我需要知道在给定时间有多少订阅进行调试 因为看起来一个事件被多次触发 但我怀疑这个错误确实是因为textBox1 TextChan
  • cygwin $'\r':命令未找到错误

    我稍微修改了一个项目 在调试下它运行得很好 当我尝试在不调试的情况下构建它时 它显示错误 无法修复它 make Making all in third party make 1 Entering directory cygdrive c U
  • 在 C++ 泛型编程中处理 void 赋值

    我有 C 代码 它包装任意 lambda 并返回 lambda 的结果 template
  • 将base64字符串转换为图像c#时出错

    我想在我的网页上显示图像 并单击应该下载的链接按钮 存储的图像文件以二进制格式存储在db中 将 base64 字符串转换为图像时显示错误 详细信息如下 帮助我找到合适的解决方案 谢谢 Error Code protected void Pa
  • 写入 Windows 7“预览”窗口区域

    如何使用 C 将控件写入或绘制到 Windows 7 预览区域 作为我正在讨论的示例 请在 Windows 7 中打开 Windows Media Player 并播放一首歌曲 播放歌曲时 最小化 Windows Media Player
  • 是一对一的关系不好的策略

    用户始终拥有一个钱包 一个钱包始终属于一位用户 由于我想分离与钱夹相关的属性 我创建了 Wallet 对象并能够跟踪钱交易 我创建了 public Wallet Entity
  • Microsoft Graph API 调用无限期挂起

    我正在尝试使用 Microsoft Graph 查询 Azure Active Directory 用户信息 我可以很好地进行身份验证 但是当我尝试查询用户信息时client Users我的应用程序无限期挂起 没有超时 没有错误 只是挂起

随机推荐

  • 在 c:\ProgramFiles\ 下时忽略 .Net app.config 文件

    我有一个奇怪的现象 我有 Net 4 0 应用程序 当 myapp exe config 位于普通的 programfiles 文件夹下时 它将被忽略 即使我删除它或在其中写入废话 myapp exe 仍然可以工作 并且在我看来 这些值是从
  • 如何使用Python3将ruamel.yaml转换为dict?

    我想要一个dict or OrderedDict from ruamel yaml 我正在使用 Python 3 8 如果有帮助的话 很乐意切换到 3 9 from ruamel yaml import YAML from collecti
  • java:查找数组中整数的频率

    我需要开发一个java要求用户输入一些内容的程序integers并找出最大和最小的数 以及这些数的平均值 然后 划分数组的集合分成若干子区间用户指定的 然后它生成一个边界点 每个边界点的长度为子区间宽度 问题是我需要创建一个频率 例如 间隔
  • 在 Linux 上编译时未定义对 mempcy@GLIBC_2.14 的引用

    我正在尝试将应用程序驱动使用 ftdi2332h 芯片的设备从 Windows 移植到 Linux 我在 ubuntu 10 04 系统上安装了 libftd2xx 库按照这些说明 http www ftdichip com Drivers
  • Python:合并嵌套列表

    初学者在这里 我有 2 个要合并的嵌套列表 list1 a b c d e f g h list2 p q r s t u v w 我正在寻找的输出是 list3 a p q b c r s d e t f g h u v w 这可以在没有
  • 如何在模板形式 Angular 2 中使用最小、最大验证[重复]

    这个问题在这里已经有答案了 我尝试在模板表单中使用 min 验证 但它不起作用 如何以模板形式使用它 感谢您的帮助
  • 启动时启动服务但不进行任何活动

    我想创建一个仅包含服务 无活动 的应用程序 该服务必须在启动时启动 我的问题是 如果没有活动 启动接收器似乎不会调用 我用下面的例子进行了测试 我有不同的文件 MyReceiver java package com test teststa
  • Android 谷歌地图圆圈平滑改变半径

    我想控制按进度条循环 但是谷歌地图APIsetRadius变化并不顺利 如何平滑改变圆半径 这是我的源代码 private Circle circle public void onMapReady final GoogleMap googl
  • 在 bash 函数中生成后台进程

    我正在编写一个 Bash 函数来启动需要从某个文件夹启动的服务器 但我不希望启动该服务器影响我当前的工作 我写了以下内容 function startsrv pushd cd TRUNK SERVERCOMMAND popd 我的变量都已设
  • Django:如何从管理界面调用管理自定义命令执行?

    参考 从代码执行管理命令 https stackoverflow com questions 907506 how can i call a custom django manage py command directly from a t
  • 如何在 TFS 2015 中链接构建?

    TFS 2015 中是否有一种方法可以进行两个构建 以便每当第一个构建 成功 完成时就会触发第二个构建 那里are https tfschainbuild codeplex com 解决方案 https blog stangroome co
  • SET IDENTITY_INSERT [表] ON 不起作用

    我想在指定 Id 的位置插入一些记录 以便将数据迁移到我想要保持现有关系完整性的位置 为此 我直接在 SSMS 中的表上运行以下命令 SET IDENTITY INSERT CRMTItem ON 然而 当我从 C 插入一个 Id 为 1
  • 调整大小时标题不响应

    我有一个表格 当我调整大小时它不会显示我的标题Steps在网络视图上 它确实显示得很完美 但是当我调整大小时 我看不到我的步骤标题 有没有办法使用 css 或 jstl jsf 标签在下面的代码中修复此问题 谢谢您的帮助 像这样的事情 ht
  • 如何使用 Java 在 Android Wi-Fi 连接上设置 ProxySettings 和 ProxyProperties?

    如何使用 Java 以编程方式 在 Android Wi Fi 连接上设置 ProxySettings 和 ProxyProperties 由于 ipAssignment linkProperties ProxySettings 和 Pro
  • Grails - 错误分叉 Grails VM 因错误退出

    首先 我想说 我是 Grails 的初学者 在尝试遵循一些示例时 我不断收到无法解决的错误 如果问题很愚蠢 那么很抱歉 我通过命令行创建了一个虚拟应用程序 并尝试以相同的方式运行它 run app 但出现以下错误 运行 Grails 应用程
  • XSL:让原始 HTML 通过

    我正在进行 XSL 转换 我正在转换的 XML 有一个包含 html 的节点
  • 如何更改Android布局中XML片段元素的默认提示值

    默认提示值自动完成 https developers google com places android api autocomplete小部件是Search 如何将该值更改为不同的值String 尝试下面的代码 PlaceAutocomp
  • matlab矩阵中求子矩阵的通用方法

    我正在寻找一种 好 方法来在更大的矩阵 任意维数 中找到矩阵 模式 Example total rand 3 4 5 sub total 2 3 1 3 3 4 现在我希望这样的事情发生 loc matrixFind total sub 在
  • UIView 动画选项重复计数

    我的 Swift 代码遇到一些问题 我试图使 UIImageView 对象消失并重新出现一次 但在让动画仅播放一次方面遇到一些问题 IBOutlet weak var ball UIImageView IBAction func onFad
  • 复制构造函数和移动构造函数的效率差异

    C 11引入了右值引用的新概念 我在某处读到它并发现以下内容 class Base public Base Default Ctor Base int t Parameterized Ctor Base const Base b Copy