C++11 右值与移动语义

前言:

我们首先汇总一下在C++11中新的变化:

1、新容器 —— unodered_xxx

2、新接口

  • cbegin等,无关痛痒
  • initializer_list系列的构造
  • push_xxx / insert / emplace 等增加右值引用插入版本,意义重大,提高效率
  • 容器新增移动构造和移动赋值,也可以减少拷贝,提高效率

毫无疑问,其中最重要的就是右值引用和移动构造赋值,接下来我们重点讲解有关知识~

一、右值引用

我们首先要清楚跟右值相对的概念,左值和左值引用。

什么是左值,什么是左值引用?

答:

左值是一个表达式,我们可以获取它的地址。一般可以对它进行赋值(加上const变成常量就修改不了)。

左值引用就是给左值取别名。

int& func2()
{const int x = 2;return x;
}int main()
{// 以下的p、b、c、*p, func2()返回值 都是左值int* p = new int(0);int b = 1;const int c = 2;const int* ptr1 = &c;int* ptr2 = &func2();printf("%p %p\n", ptr1, ptr2);return 0;
}

什么是右值,什么是右值返回?

答:

右值也是表达式,如字面常量、表达式返回值、函数返回值(不能是左值引用返回)。

右值可以出现在赋值符号的右边,但是不能出现在赋值符号的左边,右值不能取地址

右值引用就是对右值的引用,给右值取别名。

int main()
{
double x = 1.1, y = 2.2;
// 以下几个都是常见的右值
10;
x + y;
fmin(x, y);
// 以下几个都是对右值的右值引用
int&& rr1 = 10;
double&& rr2 = x + y;
double&& rr3 = fmin(x, y);
// 这里编译会报错:error C2106: “=”: 左操作数必须为左值
10 = 1;
x + y = 1;
fmin(x, y) = 1;
return 0;
}

注意右值引用是两个&,跟左值引用一个&做区分。

小总结:

语法上:

引用都是别名,不开空间,左值引用是给左值取别名,右值引用是给右值取别名。

底层:(了解)

引用是用指针实现的。左值引用是存当前左值的地址。右值引用,是把当前右值拷贝到栈上的一个临时空间,存储这个临时空间的地址。

TIP:右值引用与左值引用的交叉

int main()
{// 左值引用能否给右值取别名 不能// 但是const左值引用可以const int& r1 = func1();const int& r2 = 10;// 右值引用能否给左值取别名 不能// 但是右值引用可以给move以后的左值可以int x = 0;int&& rr1 = move(x);return 0;
}

    左值引用能否给右值取别名——不能
    但是const左值引用可以

    右值引用能否给左值取别名——不能
    但是右值引用可以给move以后的左值可以

引用的意义:

本质为了减少拷贝!


所以右值引用到底有什么用?(左值引用没有解决所有问题)

我们首先看看左值引用解决了什么问题?

1、传参的拷贝解决了

浅拷贝不用考虑,深拷贝时我们采用引用取别名的方法,将传参不用再额外开辟空间。减少拷贝

2、传返回值的问题解决了一部分

函数调用结束时,返回值仍然存在,不用开辟新空间(引用返回)

但是

局部对象(出了作用域就销毁的对象)返回的拷贝问题,只能传值返回,就存在拷贝,如果有些对象会拷贝会消耗巨大的问题没有解决!

注意深拷贝是一种极度的资源浪费,因为深拷贝过后,临时创建的对象马上又销毁。

这里就需要我们的右值引用!

C++11对右值概念的解释,细分便于理解

1、纯右值(内置类型的右值)如:10 / a + b

2、将亡值(自定义类型的右值)如:匿名对象、传值返回函数

优化之前:

解释:

原本的str是左值,但是会有拷贝构造产生的临时值,也就是右值(将亡值),这里利用将亡值的特性使用移动构造,因此是1次拷贝,1次移动。

优化之后:

直接隐式将原本的左值str move()转换变成右值,这样就可以不用再创建临时对象进行拷贝构造,直接一次移动构造就可以完成!!!

优化点:

1、将一次拷贝、一次移动合二为一,省去中间的临时对象

2、隐式的强行对move(str)识别为右值

总结:

浅拷贝的类不需要移动构造  

深拷贝的类才需要移动构造

深拷贝对象传值返回只需要移动资源,代价很低

问题:右值不能改变,那怎么转移你的资源呢?

答:

右值被右值引用后,右值引用的属性是左值,可以被改变,这样资源才能被转移!

右值引用延长了资源的生命周期!!!并不是延长对象的生命周期。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/6086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

领域驱动设计(DDD)笔记(一)基本概念

文章链接 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客领域驱动设计(DDD)笔记(二)代码组织原则-CSDN博客 DDD基本概念 DDD 是一种面向复杂需求的软件设计方法,将软件开…

【Vue3】openlayers加载瓦片地图并手动标记坐标点

目录 一、创建Vue3项目 二、openlayers加载瓦片地图(引js文件版) 2.1 将以下的文件复制到public下 2.2 index.html引入ol脚本 2.3 删除项目自带的HelloWorld.vue,创建Map.vue 2.4 编码Map.vue 2.5 修改App.vue 2.6 启动项目测试 三、…

通信光缆主要敷设方式有哪些(续)

在《通信光缆主要敷设方式有哪些》一文中,介绍了光缆的直埋、架空和管道敷设方式。此外,根据敷设场景的不同,光缆的常见敷设方式还包括:高铁槽道内敷设、水底敷设、墙壁敷设、引上、室内敷设等。 1 高铁槽道内光缆敷设 光缆顺沿高…

vscode设置免密登录远程服务器

文章目录 1. 问题描述2. 解决方案3. 原理 1. 问题描述 当我们使用vscode的ssh连接远程服务器后,过一段时间后,总是要求登录服务器的密码。 这就导致一个麻烦就是: 无论是在公司还是在学校,密码往往不是自己设置的,所以记忆起来就…

《QT实用小工具·五十二》文本或窗口炫酷有趣的滚动条——果冻条

1、概述 源码放在文章末尾 该项目实现了文本或窗口纤细的滚动条——果冻条 一个可以像弓弦一样拉出来,并且来回弹动的普通滚动条。 思路为此,但发现实际效果更像条状果冻,并且略有谐音, 故,称之为——“果冻条”&am…

【QT学习】12.UDP协议,广播,组播

一。Udp详细解释 UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP相比,UDP不提供可靠性、流量控制、拥塞控制和错误恢复等功能,但由于其简单性和低开销&#x…

【Linux-点灯烧录-SD卡/USB烧写】

目录 1. 烧写方式2. 烧写之代码编译2.1 led.s->led.o2.2 led.o->led.elf2.3 led.elf->led.bin2.4 反汇编:led.elf->led.dis 3. 烧写之烧录到SD卡上:3.1 开启烧录软件权限:3.2 确定SD卡的格式:FAT323.3 烧录到SD卡上3.…

学习Rust的第22天:mini_grep第2部分

书接上文,在本文中,我们学习了如何通过将 Rust 程序的逻辑移至单独的库箱中并采用测试驱动开发 (TDD) 实践来重构 Rust 程序。通过在实现功能之前编写测试,我们确保了代码的可靠性。我们涵盖了基本的 Rust 概念,例如错误处理、环境…

ChatGPT理论分析

ChatGPT "ChatGPT"是一个基于GPT(Generative Pre-trained Transformer)架构的对话系统。GPT 是一个由OpenAI 开发的自然语言处理(NLP)模型,它使用深度学习来生成文本。以下是对ChatGPT进行理论分析的几个主…

移动机器人系统与技术:自动驾驶、移动机器人、旋翼无人机

这本书全面介绍了机器人车辆的技术。它介绍了道路上自动驾驶汽车所需的概念。此外,读者可以在六足机器人的构造、编程和控制方面获得宝贵的知识。 这本书还介绍了几种不同类型旋翼无人机的控制器和空气动力学。它包括各种旋翼推进飞行器在不同空气动力学环境下的模…

基于vmware虚拟机中yum源的配置

1.首先需确保虚拟机中已经连接了光盘映像(如图在虚拟机右下方从左往右第二个) 2.在虚拟机中找到光盘映像文件(默认在/dev的sr0) 3.将光盘文件挂载(挂载后才可读取) 为方便每一次开机之后自动挂载&#xff…

学浪视频怎么下载保存到本地

你是否曾经因为想要保存一份珍贵的学浪视频却苦于无法下载而感到烦恼?现在,我将向你揭示一个简单易行的方法,让你轻松地将学浪视频保存到本地,随时随地享受学习的乐趣。你是否曾经因为想要保存一份珍贵的学浪视频却苦于无法下载而…

未来科技的前沿:深入探讨人工智能的进展、机器学习技术和未来趋势

文章目录 一、人工智能的定义和概述1. 人工智能的基本概念2. 人工智能的发展历史 二、技术深入:机器学习、深度学习和神经网络1. 机器学习2. 深度学习3. 神经网络 三、人工智能的主要目标和功能1. 自动化和效率提升2. 决策支持和风险管理3. 个性化服务和预测未来 本…

初始数据类型

注释补充 在我们编写任何代码的时候,都有一个叫做注释的功能 在golang中有两种 单行注释 // 如下图所示 加入了注释的话,代码在执行的时候会自动忽视这段内容 //fmt.Println("天上") //fmt.Println("天下") //fmt.Println("唯…

MySQL商城数据库88张表结构(46—50)

46、消息队列表 CREATE TABLE dingchengyu消息队列表 (id int(11) NOT NULL AUTO_INCREMENT COMMENT 序号,userId int(11) DEFAULT NULL COMMENT 用户id,msgTtype tinyint(4) DEFAULT 0 COMMENT 消息类型,createTime datetime DEFAULT NULL COMMENT 创建时间,sendTime datetim…

本地基于知识库的大模型的使用教程

本地基于知识库的大模型的使用教程 启动 双击 大模型启动.bat文件,内容如下: cmd /k "cd /d G:\Anaconda3\Scripts && activate.bat && cd /d D:\docdb_llm && conda activate python3.11 && python startup.py…

Web安全研究(七)

NDSS 2023 开源地址:https://github.com/bfpmeasurementgithub/browser-fingeprint-measurement 霍普金斯大学 文章结构 introbackground threat model measurement methodology step1: traffic analysisstep2: fingerprint analysis dataset attack statisticsbro…

【EI会议|稳定检索】2024年传感技术与图像处理国际会议(ICSTIP 2024)

2024 International Conference on Sensing Technology and Image Processing 一、大会信息 会议名称:2024年传感技术与图像处理国际会议会议简称:ICSTIP 2024收录检索:提交Ei Compendex,CPCI,CNKI,Google Scholar等会议官网:htt…

nginx变量自定义日志收集

内置变量 $remote_addr;存放了客户端的地址,注意是客户端的公网IP,也就是一家人访问一个网站,则会显示为路由器的公网IP。 $args;变量中存放了URL中的指令 [rootlocalhost conf.d]# cat pc.conf server {listen 80;se…

调教AI给我写了一个KD树的算法

我不擅长C,但是目前需要用C写一个KD树的算法。首先我有一份点云数据,需要找给定坐标范围0.1mm内的所有点。 于是我开始问AI,他一开始给的答案,完全是错误的,但是我一步步给出反馈,告诉他的问题,…