【C++】 C++11:左值、右值,移动语义与完美转发
目录一、左值与右值二、左值引用的短板三、右值引用与移动语义移动语义变“复制”为“窃取”移动构造与移动赋值示例四、强制“窃取”std::move() 的妙用五、完美转发与 std::forward1. 披着右值皮的“万能引用”2. 属性退化的痛点3. std::forward 完美转发总结核心考点在 C 的学习路线上C11 是一次极其重要的进化。相比于 C98/03C11 包含了约 140 个新特性能更好地用于系统开发和库开发提升程序员的开发效率。而在这些新特性中右值引用和移动语义无疑是最核心、也是最能带来性能飞跃的语法特性。一、左值与右值在了解引用之前我们必须先分清什么是“左值”什么是“右值”左值是一个表示数据的表达式如变量名或解引用的指针。我们可以获取它的地址可以对它赋值。左值可以出现在赋值符号的左边。右值也是一个表示数据的表达式如字面常量、表达式返回值、函数返回值等。右值不能出现在赋值符号左边不能取地址。inta10;// a 是左值10 是右值int*pnewint(0);// p 和 *p 是左值intba10;// a 10 的结果是一个右值二、左值引用的短板传统的 C 语法中就有引用的语法C11 中新增了右值引用语法特性因此我们之前学习的引用就叫做左值引用使用表示。无论左值引用还是右值引用都是给对象取别名。左值引用在做函数参数和做返回值时都可以提高效率。但是它有一个致命的短板当函数返回对象是一个局部变量出了函数作用域就不存在了就不能使用左值引用返回只能传值返回。stringto_string(intvalue){string str;// ... 将 value 转换为字符串放入 strreturnstr;// 出作用域 str 被销毁只能传值返回}传值返回会导致至少 1 次拷贝构造如果是一些旧一点的编译器可能是两次拷贝构造。对于包含大量堆内存数据的容器或字符串这种深拷贝极其拖累程序效率。三、右值引用与移动语义为了补齐左值引用的短板C11 提出了右值引用使用表示也就是对右值的引用给右值取别名。intrr110;doublerr2xy;移动语义变“复制”为“窃取”有了右值引用我们可以增加移动构造和移动赋值函数。移动构造本质是将参数右值的资源窃取过来占位已有那么就不用做深拷贝了。所以它叫做移动构造就是窃取别人的资源来构造自己从而提高效率。移动构造与移动赋值示例在自定义string类中移动构造和移动赋值是这样工作的// 拷贝构造深拷贝性能开销大string(conststrings):_str(nullptr){stringtmp(s._str);swap(tmp);}// 移动构造窃取资源快如闪电string(strings):_str(nullptr),_size(0),_capacity(0){// 直接调用 swap 交换指针接管资源swap(s);}// 移动赋值窃取资源stringoperator(strings){swap(s);return*this;}intmain(){bit::string retbit::to_string(1234);//调用移动构造bit::string ret1;ret1bit::to_string(1234);//调用移动构造和移动赋值return0;}当执行bit::string ret bit::to_string(1234);时编译器会识别出to_string的返回值是一个右值如果既有拷贝构造又有移动构造调用就会匹配调用移动构造没有新开空间拷贝数据所以效率提高了。当执行bit::string ret1; ret1 bit::to_string(1234);时我们看到调用了一次移动构造和一次移动赋值。因为如果是用一个已经存在的对象接收编译器就没办法优化了。bit::to_string函数中会先用str生成构造生成一个临时对象但是我们可以看到编译器很聪明的在这里把str识别成了右值调用了移动构造。然后在把这个临时对象做为bit::to_string函数调用的返回值赋值给ret1这里调用的移动赋值。STL中的容器都是增加了移动构造和移动赋值四、强制“窃取”std::move() 的妙用按照语法右值引用只能引用右值。但当我们需要用右值引用去引用一个左值实现移动语义时可以通过std::move()函数将左值转化为右值。C11 中的std::move()函数名字具有迷惑性它并不搬移任何东西唯一的功能就是将一个左值强制转化为右值引用然后实现移动语义。strings1(hello world);// 我们把 s1 move 处理以后会被当成右值调用移动构造strings3(std::move(s1));// 警告这里要注意一般不要这样用因为 s1 的资源被转移给了 s3s1 被置空了五、完美转发与 std::forward当我们把右值引用和模板结合在一起时会发生一些奇妙的化学反应。在这里我们必须要了解一个概念万能引用与完美转发。1. 披着右值皮的“万能引用”在模板中并不总是代表右值引用。模板中的是万能引用其既能接收左值又能接收右值。templatetypenameTvoidPerfectForward(Tt){// 这里的 t 既能接收左值也能接收右值}2. 属性退化的痛点模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力。但是这里存在一个巨大的坑引用类型的唯一作用就是限制了接收的类型后续使用中都退化成了左值。也就是说即使你给PerfectForward传了一个右值在函数内部t有了名字它可以被取地址它本身就变成了一个左值。如果我们在这时继续把t传给底层的其他函数底层函数永远只会把它当成左值处理原本的右值属性丢失了移动语义也就无法触发。3. std::forward 完美转发我们希望能够在传递过程中保持它的左值或者右值的属性就需要用完美转发。C11 提供了std::forward。std::forwardT(t)在传参的过程中保留对象原生类型属性如果你原来是左值传下去还是左值如果你原来是右值传下去依旧是右值。voidFun(intx){cout左值引用endl;}voidFun(intx){cout右值引用endl;}templatetypenameTvoidPerfectForward(Tt){// std::forwardT(t) 在传参的过程中保持了 t 的原生类型属性Fun(std::forwardT(t));}intmain(){inta10;PerfectForward(a);// a 是左值Fun 会打印 左值引用PerfectForward(std::move(a));// move(a) 是右值Fun 会打印 右值引用return0;}完美转发在 STL 的很多底层实现比如可变参数模板、emplace_back等中被大量使用它是 C11 高效泛型编程的基石。总结核心考点左值引用只能引用左值但const左值引用既可引用左值也可引用右值其短板是当函数返回局部对象时只能传值返回。右值引用只能引用右值但是可以引用 move 以后的左值。移动构造/移动赋值本质是将参数右值的资源窃取过来不用做深拷贝完美解决了传值返回导致的性能瓶颈。std::move()的唯一功能就是将一个左值强制转化为右值引用用于实现移动语义。

相关新闻

电容器跳闸原因分析与预防维护全攻略

电容器跳闸原因分析与预防维护全攻略

1. 电容器跳闸问题的典型表现与初步判断当配电系统中电容器出现跳闸时,通常伴随着以下可观察现象:配电柜中电容器支路的断路器或熔断器动作断开,功率因数表显示数值异常下降(可能从0.95骤降至0.8以下),同时…

2026/7/28 14:12:48 阅读更多 →
MicroPython条件与循环:嵌入式编程的逻辑基石与实战技巧

MicroPython条件与循环:嵌入式编程的逻辑基石与实战技巧

1. 从“顺序执行”到“智能决策”:为什么需要条件与循环?写代码,本质上是在教计算机做事。最开始,我们写的代码就像一份简单的食谱清单,计算机从上到下,一行一行地执行,这就是“顺序执行”。比如…

2026/7/28 14:12:48 阅读更多 →
git操作命令

git操作命令

1 首次克隆 代码git clone 2 查询本地状态git status3 添加缓存 添加指定文件git add <文件名>添加 所有git add .删除缓存1 不会删除物理文件&#xff0c;只是将已经add的文件删除git rm --cached <文件名 >2 从缓存区删除某一个目录下所有文件git rm -r --cach…

2026/7/28 14:11:47 阅读更多 →

最新新闻

大数据开发者必学:C++组合类构造函数原理与实战应用

大数据开发者必学:C++组合类构造函数原理与实战应用

1. 项目概述&#xff1a;为什么大数据开发者必须啃下C这块硬骨头&#xff1f; 最近在帮团队面试大数据开发岗位的候选人&#xff0c;发现一个挺有意思的现象&#xff1a;很多简历上写着精通Spark、Flink、Hadoop的工程师&#xff0c;一旦被问到一些底层原理或者需要手写一些稍微…

2026/7/29 15:26:17 阅读更多 →
电子骰子:嵌入式系统入门教学的完美实践项目

电子骰子:嵌入式系统入门教学的完美实践项目

1. 项目缘起&#xff1a;为什么选择“电子骰子”作为机器人制作的入门课&#xff1f; 在机器人或创客教育的入门阶段&#xff0c;我们常常面临一个难题&#xff1a;如何找到一个项目&#xff0c;既能激发学生的兴趣&#xff0c;又能串联起硬件、编程和物理交互的核心概念&#…

2026/7/29 15:26:17 阅读更多 →
近距离显示解决方案:传感器技术与应用实践

近距离显示解决方案:传感器技术与应用实践

1. 近距离显示解决方案概述 Proximity Display Solution&#xff08;近距离显示解决方案&#xff09;是一种基于传感器技术的智能交互系统&#xff0c;主要用于检测用户与显示设备的距离变化并触发相应的显示控制逻辑。这种技术最早可以追溯到2014年智能手机开始普及的距离传感…

2026/7/29 15:26:17 阅读更多 →
SpringBoot构建高保真艺术品展示平台的技术实践

SpringBoot构建高保真艺术品展示平台的技术实践

1. 项目背景与核心需求去年参与了一个美术馆的数字化改造项目&#xff0c;需要将线下展览搬到线上。这个基于SpringBoot的艺术作品展示平台&#xff0c;本质上解决的是艺术品在数字空间的呈现、交互与传播问题。不同于普通商品展示&#xff0c;艺术作品对色彩还原度、细节放大、…

2026/7/29 15:26:17 阅读更多 →
二叉树基础概念、存储结构与常见问题解析

二叉树基础概念、存储结构与常见问题解析

1. 二叉树基础概念与核心定义 二叉树是数据结构中最基础也最重要的非线性结构之一&#xff0c;它由n&#xff08;n≥0&#xff09;个有限节点组成的有序集合。这个集合要么为空&#xff08;n0&#xff09;&#xff0c;要么由一个根节点和两棵互不相交的、分别称为左子树和右子树…

2026/7/29 15:26:16 阅读更多 →
用游戏手柄控制3D打印机:AutoHotkey脚本实现G代码实时操控

用游戏手柄控制3D打印机:AutoHotkey脚本实现G代码实时操控

1. 项目概述&#xff1a;当游戏手柄遇上3D打印机 作为一名常年和3D打印机、CNC机床打交道的工程师&#xff0c;我一直在寻找更直观、更符合人体工学的设备操控方式。传统的3D打印机控制&#xff0c;要么是通过触摸屏点按&#xff0c;要么是通过上位机软件&#xff08;如Cura、P…

2026/7/29 15:25:16 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02&#xff1a;合并知识功能&#xff0c;给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中&#xff0c;我们学习了如何构建一个基础的 AI 问答系统&#xff0c;通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景&#xff1a;…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行&#xff1a;AI Agent的范式转变过去两年&#xff0c;大语言模型最显著的应用形态是聊天机器人——用户提问&#xff0c;AI回答。但真正的生产力革命发生在2023年下半年&#xff1a;当AI学会主动调用工具完成任务时&#xff0c;生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档&#xff0c;可以直接使用&#xff01;系统支持图片、视频、摄像头等多种方式检测裂缝&#xff0c;功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像&#xff01; pubg绝地求生目标检测数据集 1分类&#xff1a;e_body&#xff0c;14905个标签&#xff0c;txt格式 共计14244张图&#xff0c;99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别&#xff1a; allies enemy tag图片总量&#xff1a;7247张训练集&#xff1a;5139张验证集&#xff1a;1425张测试集&#xff1a;683张标注状态&#xff1a;全部已标注&#xff0c;即拿即用数据格式&#xff1a;支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻