C++ 右值引用深入理解:特性、优化与底层
目录
一、左右值的概念及右值的种类
二、左值引用与右值引用
左值引用给右值取别名:
右值引用给左值取别名:
三、引用的意义及左值引用的场景
四、移动构造:
右值引用在底层里的实现:
一、左右值的概念及右值的种类
在 C++ 中,左右值的区分对于理解语言的行为至关重要。一般来说,可以取地址的是左值,不可以取地址的是右值。同时,被 const 修饰的通常也被视为左值。
右值主要包括以下几种类型:
- 常量,例如
10,它们在程序运行期间具有固定的值,且通常存储在只读内存区域。 - 临时对象,如
string("1111"),这些对象是在表达式中临时创建的,通常在包含它们的完整表达式结束后就可能被销毁。 - 匿名对象,例如
string("666"),没有名字的对象,同样也是临时创建的,生命周期较短。
//右值10;//常量string("1111");//临时对象string("666");//匿名对象
二、左值引用与右值引用
-
左值引用给右值取别名:
- 不能直接用左值引用给右值取别名,但是使用
const左值引用是可以的。这是因为const左值引用可以绑定到临时对象,确保在引用期间不会修改这个临时对象。例如const int& a = 10;,这里a是一个常量引用,绑定到了右值10。
- 不能直接用左值引用给右值取别名,但是使用
-
右值引用给左值取别名:
- 不能直接用右值引用给左值取别名,但是可以通过
std::move将左值转换为右值后,再用右值引用进行引用。例如int c = 100; int&& b = move(c);和int&& d = (int&&)c;。 std::move的作用是将左值转换为右值,本质上类似于强制类型转换。在底层实现中,无论是左值引用还是右值引用,实际上都是指针的形式,这也说明了在底层并没有真正的 “引用” 概念,而move更多的是在语法层面上进行类型转换。
- 不能直接用右值引用给左值取别名,但是可以通过
int c = 100;
const int& a = 10;
int&& b = move(c);
int&& d = (int&&)c;
move:将左值转化为右值,本质等同于强转,所以上面的b与d没区别
move的讲解:move - C++ Reference (cplusplus.com)
三、引用的意义及左值引用的场景
引用在 C++ 中有重要的意义,主要是减少拷贝操作,提高程序的性能。
左值引用主要解决的场景包括引用传参和引用传返回值。通过引用传参,可以避免不必要的对象拷贝,特别是对于大型对象,这种方式可以显著提高程序的效率。在函数返回值时,如果返回左值引用,可以避免返回对象时的拷贝构造,直接返回对象的引用,提高程序性能。
然而,左值引用在某些情况下并没有彻底解决问题。例如,当传值返回的时候,如果返回的是左值,那么只能通过拷贝构造来解决问题。但是当遇到大数据结构(如 std::list 等)的深拷贝时,会非常浪费时间,这时候右值引用的价值就体现出来了。
四、移动构造:
对于自定义类,可以定义移动构造函数来处理右值。例如对于 std::string 类,移动构造函数的形式可能是 string(string&& s),在这个函数中,通过 swap(s) 操作,将即将消亡的右值对象的数据交换过来,避免了不必要的拷贝操作。这样做的好处是,获取要消亡的数据,把自身不需要的数据给右值对象 s,让它去销毁,而自身获取有用的数据,不再需要进行拷贝。
string(string&& s)
{swap(s);
}
只有进行深拷贝的类才有移动构造的意义,因为只有在深拷贝的情况下,避免拷贝操作才能带来显著的性能提升。
右值返回种类:
存右值:内置类型右值
将亡值:类类型的右值
移动构造:swap(s),将要消亡的交换,获取要消亡的数据,把‘我’不要的数据给s,让他去销毁,而我获取有用的数据,不需要拷贝了吗
拷贝构造:传值返回时,编译器将要先把返回的数据先生成临时对象在拷贝给所需的对象优化成了直接把返回的数据拷贝给所需对象,将俩次拷贝优化成了一次
深拷贝的类才有移动构造的意义
在string s1 (s2)编译器开的优化大,构造加拷贝/移动构造 = 直接构造。相当于直接引用的main函数的对象—vs2022.不是所以编译器都这样 构造可以这么激进的优化,但是赋值不可以
移动赋值string s1 = (s2)
右值引用在底层里的实现:
R1右值引用的属性本身是---》左值 :因为swap什么的需要修改
左值和右值可以来回切,本质只是语法层的限制
相关文章:
C++ 右值引用深入理解:特性、优化与底层
目录 一、左右值的概念及右值的种类 二、左值引用与右值引用 左值引用给右值取别名: 右值引用给左值取别名: 三、引用的意义及左值引用的场景 四、移动构造: 右值引用在底层里的实现: 一、左右值的概念及右值的种类 在 C …...
C# 文件操作
文章目录 文件系统FileInfo和DirectoryInfo类完成一个文件的拷贝判断一个文件是否存在FileInfo和DirectoryInfo的属性列表FileInfo和DirectoryInfo的方法列表读写文件文件系统 下面的类用于浏览文件系统和执行操作,比如移动,复制和删除文件。 System.MarshalByRefObject 这个…...
FFmpeg 4.3 音视频-多路H265监控录放C++开发三 :安装QT5.14.2, 并将QT集成 到 VS2019中。
一,安装QT, 重点:在安装QT的时候要安装msvc201x版本的组件, 二 , 安装 qt-vs-tools Index of /development_releases/vsaddin/2.8.1 三,需要安装过 windows10 SDK,一般我们在安装vs2019的时候就…...
Linux 累加计算递归算法汇编实现
1...n可以使用公式计算,同时也是递归实现的很好例子,其c实现代码为 int f(int i) {i && (if(i-1));return i; } 其终止条件为0,此时i && (if(i-1))表达式不成立,不计算if(i-1)直接返回0&…...
明日周刊-第23期
十月已过半,气温也转凉了,大家注意保温哦。冬吃萝卜,夏吃姜,在快要到来的冬季大家可以选择多吃点萝卜。 配图是本周末去商场抓娃娃的时候拍的照片,现在抓娃娃单次普遍都控制在1块钱以下了,还记得多年前的抓…...
kubernets(二)
集群操作 查看集群信息 kubectl get查看各组件信息 格式:kubectl get 资源类型 【资源名】 【选项】 events #查看集群中的所有日志信息 -o wide # 显示资源详细信息,包括节点、地址... -o yaml/json #将当前资源对象输出至 yaml/json 格式文…...
《YOLO 标注工具全览》
《YOLO 标注工具全览》 一、YOLO 标注工具的重要性二、常见的 YOLO 标注工具介绍(一)LabelImg(二)Yolo_Label(三)在线标注工具 Make Sense(四)Ybat - YOLO BBox Annotation Tool&…...
财富思维学习
四大象限: 人类财富创造史经历的五个阶段: 1、黄色(土地)财务阶段:拥有土地和劳动力是财富的要求 2、蓝色(海)财富阶段:谁拥有贸易的通道谁就拥有财富(如港口ÿ…...
python爬虫加解密分析及实现
第一种: 1、找到加密的接口地址,通过加密的接口地址全局搜索 2、通过打断点的方式,操作页面,跑到断点处时,即可找到加密串,如图二; 3、找到用的是哪种加密方式,如: cr…...
用Java做智能客服,基于私有知识库
构建Java智能客服系统的整体思路 使用Java构建智能客服系统的整体思路是: 首先将客服QA文档以Word形式导入到系统中,通过向量化处理存入知识库。 当用户提出问题时,系统会根据问题内容从知识库中检索相关的上下文信息,并结合大…...
软考(网工)——网络安全
文章目录 🕐网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型 🕑现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 🕒Hash …...
如何给手机换ip地址
在当今数字化时代,IP地址作为设备在网络中的唯一标识,扮演着举足轻重的角色。然而,有时出于隐私保护、网络访问需求或其他特定原因,我们可能需要更改手机的IP地址。本文将详细介绍几种实用的方法,帮助您轻松实现手机IP…...
kafkamanager安装
一.下载kafkamanager2.0 https://download.csdn.net/download/cyw8998/89892482 二.修改配置文件 解压缩 unzip kafka-manager-2.0.0.0.zip vim application.conf /opt/module/kafka-manager-2.0.0.0/conf/application.conf 添加以下内容:(连接zooke…...
笔记本电脑U口保护分享
在前司时候,经常遇到各种硬件类的问题,但是之前没时间分享,现在来给大家分享一下,常见的问题及如何保护。 1.接口接触不良。这个一般发生于使用时间长了,可以用细砂纸,轻轻摩擦后再进行尝试。 2.接口失灵…...
OpenCV高级图形用户界面(20)更改窗口的标题函数setWindowTitle()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在OpenCV中,cv::setWindowTitle函数用于更改窗口的标题。这使得您可以在程序运行时动态地更改窗口的标题文本。 函数原型 void cv::…...
结构体指针的初始化以及结构体变量作为函数实参传递时易混淆的知识点
结构体指针初始化以及结构体变量作为函数实参传递时易混淆的知识点 首先要明确,结构体类型是用户自己定义的一种数据类型,其本质上与int, char等标准数据类型是一致的 **1.**因此,在进行结构体指针的初始化时,应该这样写&#x…...
Github 2024-10-20 php开源项目日报Top10
根据Github Trendings的统计,今日(2024-10-20统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Blade项目1Laravel:表达力和优雅的 Web 应用程序框架 创建周期:4631 天开发语言:PHP, BladeStar数量:75969 个Fork数量:24281 次…...
C++ 算法学习——1.3 双向深度优先搜索
双向深度优先搜索(Bidirectional Depth-First Search)是一种图搜索算法,旨在通过从起始节点和目标节点同时开始,沿着深度优先搜索的路径向前探索,以减少搜索空间并提高搜索效率。 1. 基本原理 双向深度优先搜索同时从…...
Artistic Oil Paint 艺术油画着色器插件
只需轻轻一点,即可将您的视频游戏转化为艺术品!(也许更多…)。 ✓ 整个商店中最可配置的选项。 ✓ 六种先进算法。 ✓ 细节增强算法。 ✓ 完整的源代码(脚本和着色器)。 ✓ 包含在“艺术包”中。 …...
记一次left join联表查询的索引失效场景
结论:关联表的列的字符集不一致导致的 场景:user_t(用户表)、org_t(机构表),user_t的org_id和org_t的id是一对一关系 1.explain发现org_t表未走索引,但是org_t的id字段默认存在主键…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
