当前位置: 首页 > news >正文

C++ 右值引用深入理解:特性、优化与底层

目录

一、左右值的概念及右值的种类

二、左值引用与右值引用

左值引用给右值取别名:

右值引用给左值取别名:

三、引用的意义及左值引用的场景

四、移动构造:

右值引用在底层里的实现:


一、左右值的概念及右值的种类

在 C++ 中,左右值的区分对于理解语言的行为至关重要。一般来说,可以取地址的是左值,不可以取地址的是右值。同时,被 const 修饰的通常也被视为左值。

右值主要包括以下几种类型:

  1. 常量,例如 10,它们在程序运行期间具有固定的值,且通常存储在只读内存区域。
  2. 临时对象,如 string("1111"),这些对象是在表达式中临时创建的,通常在包含它们的完整表达式结束后就可能被销毁。
  3. 匿名对象,例如 string("666"),没有名字的对象,同样也是临时创建的,生命周期较短。
	//右值10;//常量string("1111");//临时对象string("666");//匿名对象

二、左值引用与右值引用

  1. 左值引用给右值取别名

    • 不能直接用左值引用给右值取别名,但是使用 const 左值引用是可以的。这是因为 const 左值引用可以绑定到临时对象,确保在引用期间不会修改这个临时对象。例如 const int& a = 10;,这里 a 是一个常量引用,绑定到了右值 10
  2. 右值引用给左值取别名

    • 不能直接用右值引用给左值取别名,但是可以通过 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、蓝色(海)财富阶段:谁拥有贸易的通道谁就拥有财富(如港口&#xff…...

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 艺术油画着色器插件

只需轻轻一点,即可将您的视频游戏转化为艺术品!(也许更多…)。 ✓ 整个商店中最可配置的选项。 ✓ 六种先进算法。 ✓ 细节增强算法。 ✓ 完整的源代码(脚本和着色器)。 ✓ 包含在“艺术包”中。 &#x1f…...

记一次left join联表查询的索引失效场景

结论:关联表的列的字符集不一致导致的 场景:user_t(用户表)、org_t(机构表),user_t的org_id和org_t的id是一对一关系 1.explain发现org_t表未走索引,但是org_t的id字段默认存在主键…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理&#xff1a…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

面试高频问题

文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...