为什么要有移动语义?

2024-04-13

首先我要说的是,我已经阅读了有关移动语义的许多问题中的一些。这个问题不是关于如何使用移动语义,而是问它的目的是什么 - 如果我没有记错的话,我不明白为什么需要移动语义。

背景

我正在实现一个重磅课程,就这个问题而言,它看起来像这样:

class B;

class A
{
private:
    std::array<B, 1000> b;
public:
    // ...
}

当需要进行移动分配运算符时,我意识到我可以通过更改b会员到std::array<B, 1000> *b;- 那么移动可能只是删除和指针交换。

这让我产生了以下想法:现在,不应该所有非原始类型成员都是加速移动的指针(在下面更正[1] [2])(有一种情况是不应该动态分配内存的,但在这些情况下,优化移动不是问题,因为没有办法这样做)?

这是我有以下认识的地方 - 为什么创建一个类A它实际上只是容纳一个指针b所以当我可以简单地创建一个指向整个的指针时,稍后交换会更容易A类本身。显然,如果客户端期望移动速度明显快于复制,则客户端应该可以接受动态内存分配。但在这种情况下,为什么客户端不直接动态分配整个A class?

问题

难道客户端不能利用指针来完成移动语义给我们提供的一切吗?如果是这样,那么移动语义的目的是什么?

移动语义:

std::string f()
{
    std::string s("some long string");
    return s;
}

int main()
{
    // super-fast pointer swap!
    std::string a = f();
    return 0;
}

指针:

std::string *f()
{
    std::string *s = new std::string("some long string");
    return s;
}

int main()
{
    // still super-fast pointer swap!
    std::string *a = f();
    delete a;
    return 0;
}

这是每个人都说很棒的强大任务:

template<typename T>
T& strong_assign(T *&t1, T *&t2)
{
    delete t1;
    // super-fast pointer swap!
    t1 = t2;
    t2 = nullptr;
    return *t1;
}

#define rvalue_strong_assign(a, b) (auto ___##b = b, strong_assign(a, &___##b))

很好 - 两个例子中的后者可能被认为是“糟糕的风格” - 无论这意味着什么 - 但它真的值得为双&符号带来所有麻烦吗?如果之前可能抛出异常delete a被调用,这仍然不是一个真正的问题 - 只需做一个守卫或使用unique_ptr.

Edit [1]我刚刚意识到对于诸如此类的课程来说这是没有必要的std::vector它们本身使用动态内存分配并具有高效的移动方法。这只是使我的想法无效 - 下面的问题仍然存在。

Edit [2]正如下面的评论和答案中的讨论中所提到的,这一点几乎没有实际意义。人们应该尽可能多地使用值语义来避免分配开销,因为如果需要,客户端总是可以将整个事物移动到堆中。


我非常喜欢所有的答案和评论!我同意他们所有人的观点。我只是想坚持一种尚未有人提及的动机。这来自N1377 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Motivation:

移动语义主要是关于性能优化:能力 将昂贵的对象从内存中的一个地址移动到另一个地址, 同时窃取源资源以构建 以最小的花费为目标。

将当前语言和库中已存在的语义移动到 一定程度上:

  • 在某些情况下复制构造函数省略
  • auto_ptr“复制”
  • 列表::拼接
  • 交换容器

所有这些操作都涉及从一个对象转移资源 (位置)到另一个(至少在概念上)。缺少的是 统一的语法和语义,使通用代码能够任意移动 对象(就像今天的通用代码可以复制任意对象一样)。那里 标准库中有几个地方可以大大受益 来自移动对象而不是复制它们的能力(待讨论 下面深入)。

I.e. in generic代码如vector::erase,需要一个单一统一语法 to move值来填补擦除值留下的孔。一个不能用swap因为当value_type is int。并且不能使用复制分配,因为当value_type is A(OP的A)。嗯,一个could使用复制分配,毕竟我们did在 C++98/03 中,但它非常昂贵。

不应该所有非原始类型成员都是加速移动的指针吗

当会员类型为complex<double>。不妨给它上色Java。

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

为什么要有移动语义? 的相关文章

  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • Validation.ErrorTemplate 的 Wpf 动态资源查找

    在我的 App xaml 中 我定义了一个资源Validation ErrorTemplate 这取决于动态BorderBrush资源 我打算定义独特的BorderBrush在我拥有的每个窗口以及窗口内的不同块内
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框

随机推荐

  • Java - 将字符串(4 个字符)转换为 int 并返回的乐趣

    请不要问为什么 但我必须将字符串 最多 4 个字符 存储在整数值 因此 4 个字节 中 首先我写了这个并且它有效 String value AAA int sum IntStream range 0 value length limit 4
  • 与 UltraHD 兼容的 CHtmlView

    CHtmlView与 UltraHD 分辨率不兼容 实现 UltraHD 感知并不仅仅在于使用正确的 HTML CSS 打印预览机制失败并裁剪页面 许多个月前 微软承认这是一个问题 但没有解决它 我的应用程序大量使用CHtmlView用于显
  • 具有参数化脚本块的 PowerShell 函数

    我想创建一个枚举一些数据的 PowerShell 函数 并在所有出现的情况下触发脚本块 现在我已经 这不是实际的代码 但它说明了我的问题 function Invoke TenTimes CmdletBinding param Parame
  • discord.py send_message 用法

    我已经开始致力于一个项目来加速我对 python 的学习 我正在尝试重新创建一个我经常使用的不和谐机器人 因为我已经习惯了它的功能 下面是我当前的代码 import discord from discord import User from
  • 使用 Visual Studio 在线构建定义构建 SSIS 解决方案....dtproj 不受 MSBuild 支持,无法构建

    我通过 Visual Studio Online 创建了一个构建定义 用于构建 SSIS 项目 dtproj 构建似乎成功 但出现一条警告 指出 MSBuild 不支持 dtproj 无法构建 SSDT已安装在构建服务器上 有谁知道为什么会
  • Flask-后退按钮即使在注销后也会返回到会话

    我正在使用 Flask 创建一个需要登录和注销的网站 我正在使用 Flask Security 来帮助解决这个问题 我的问题是 注销后 如果点击后退按钮 我将返回到用户页面 有没有办法防止在退出后按 Flask 中的后退按钮返回会话 您可以
  • 通过Java运行cmd命令

    我发现了几个通过 Java 类运行 cmd 命令的代码片段 但我无法理解它 这是打开cmd的代码 public void excCommand String new dir Runtime rt Runtime getRuntime try
  • 当飞行模式打开时 CLLocationManager 如何获取位置

    我的应用程序使用 CLLocationManager 从设备获取位置更新 我曾假设当设备处于飞行模式时 我不会获得位置更新 但是我愿意 我之所以这么认为 是因为 Apple 表示飞行模式会关闭 Wifi 蜂窝网络 蓝牙和 GPS 看 htt
  • response.authResponse 为 null

    我编写了以下代码来检查 facebook 的登录状态 FB getLoginStatus function response if response status connected var user id response authRes
  • 为什么 XmlNodeList 是一次性的?

    我找不到这个问题的答案 只是出于好奇 为什么XmlNodeList 类 http msdn microsoft com en us library system xml xmlnodelist 28v vs 110 29 aspx在 NET
  • 如何使用 MsDeploy 设置 iisApp Provider 的部署路径?

    我正在为我的 Web 应用程序创建 Web 部署包 zip 文件 我发现我可以通过在打包站点期间包含 pubxml 并在构建期间使用 PublishProfile 属性来指定该配置文件来指定应用程序的站点名称 pubxml 有
  • 在 Vala 中使用 Glib.Settings 时如何处理错误?

    我在 Vala 应用程序中使用 Glib Settings 我想确保即使架构或密钥不可用 我的程序也能正常工作 所以我添加了一个 try catch 块 但是如果我使用不存在的密钥 程序就会出现段错误 据我了解 它甚至没有到达 catch
  • 层次结构中具有可选元素的 XPath

    正如在这个堆栈溢出答案 https stackoverflow com questions 4608097 xpath to select a table row that has a cell containing specified t
  • TSQL 选择一行或多行进行连接

    这是类似于以下的问题 TSQL 按 2 个条件之一选择行 https stackoverflow com questions 10208849 tsql select rows by one from 2 conditions 但结果与我想
  • Java:如何创建 HTTP 浏览会话

    我正在尝试创建一个向服务器发送一些 POST 请求的 Java 应用程序 第一个请求是带有身份验证信息的请求 然后 当我发送下一个请求时 我得到的答案是我的会话已过期 但我在同一秒内发送下一个请求 所以它不能超时 所以我猜想 Java 中有
  • Twitter PHP API 应用程序访问直接消息权限?

    I have set my application permissions as read Write Direct Messages as shown in the figure 我已经保存了这些设置 But when i authent
  • 如何下载并安装 lint?

    有谁知道如何获取 Mac Windows 和 Linux 的 lint sudo port install lint找不到它 我只见过 BSD 的 lint 有splint http www splint org 但是 GPL lint 重
  • 如何列出Excel中三列中值的所有可能组合?

    我有三列 每一列都有不同类型的主数据 如下所示 现在 我想要这三个单元格的所有可能组合 就像 aa kk jj aa kk ff aa ll jj aa ll ff aa mm jj 这可以用公式来完成吗 我发现一个公式有 2 列 但我无法
  • Prism的RegionManager视图切换性能

    我正在对使用 PRISM 库编写的 WPF 应用程序进行性能分析 在此应用程序中 从一个视图导航到另一视图特别慢 尤其是在远离 重 视图时 注意 来回导航时视图会被缓存并且不会重新构造 PRISM 将所有视图保留在 SingleActive
  • 为什么要有移动语义?

    首先我要说的是 我已经阅读了有关移动语义的许多问题中的一些 这个问题不是关于如何使用移动语义 而是问它的目的是什么 如果我没有记错的话 我不明白为什么需要移动语义 背景 我正在实现一个重磅课程 就这个问题而言 它看起来像这样 class B