c++11右值引用和移动语义

news2024/11/15 16:22:39

一.左值引用和右值引用

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

左值是一个表示数据的表达式(变量名解引用的指针),我们可以获取到它的地址,可以对它赋值,左值可以出现在符号的左边。使用const修饰后,不能给他赋值,但是可以取地址。左值引用就是对左值的引用,就是给左值取别名

右值也是一个表示数据的表达式(如字面常量,表达式返回值(但不能是左值引用返回!!!!!)),右值引用可以出现在符号右面,但不能出现在符号左边,不能取地址。右值引用就是给右值取别名

int add(int x, int y) {
	return x + y;
}
//左值引用和右值引用
int main()
{
	//左值
	int a = 10;
	int* p = new int(20);
	//左值引用
	int aa = a;
	int*& pp = p;


	int x = 1;
	int y = 2;
	//右值
	10;
	x + y;
	add(x, y);
	//右值引用
	int&& rr1 = 10;
	int&& rr2 = x + y;
	int&& rr3 = add(x, y);
}

但是注意,右值被引用后,会导致右值被存储到特定的位置,而且可以取到该位置的地址,并且可以修改右值引用rr1,但是要是不想被修改,可以用const的右值引用去接收:

左值引用右值引用比较

如上,左值引用不能直接引用右值,但是const左值引用可以引用右值

如上,右值引用不能饮用左值,但是可以引用move之后的左值

因为move的底层就是用到了类型转换中的static_cast。move调用后,右值就能变成左值

二.右值引用使用场景——移动构造移动赋值

1.左值引用的短板

左值引用在传参方面做的很好,但是在函数返回方面:如果返回的对象是一个局部变量,就不能使用左值引用返回了,就得先拷贝构造临时变量,再拷贝构造出返回值(不过编译器进行了优化,优化成一次构造)。

比如下面这个:

这时右值引用就派上用场了,如果写了移动构造,返回的时候就会直接进行数据交换。

先说一下右值到底有啥,首先就是纯右值,其次就是将亡值,比如函数中的局部变量在函数结束时会被释放,所以局部变量这时候就会被编译器看作右值

也就是说,上面的ret是一个将亡值,当我们写了移动构造后,他就是走移动构造这个函数。

2.移动构造

什么是移动构造,移动构造的本质就是将参数右值的资源窃取过来,占为己有。此时就不用去做深拷贝了,如下就是移动构造

如上,直接交换对象中的每一个成员变量即可(swap是咱们自己实现的)

移动赋值也一样:

这次的构造就是使用的移动构造,它能够把ret指向的堆上的资源给留下来

原来是这样的:

现在是这样的:

也就是说,传返回值时,也是会有临时对象的拷贝,但由于识别成将亡值,所以不管是临时对象还是最终的结果,都是使用的移动构造,对于其中的开始结束指针,都是指向同一块空间

通过监视也能看出来:

首先,这是进入tostring函数后ret的监视

这是接收到的string对象,会发现两者指向同一块空间

总结

1.当既有移动构造又有拷贝构造既有移动赋值又有赋值重载时,如果你是右值,那就直接转移资源,如果你是左值那就进行深拷贝

2.右值引用到底在什么时候能够体现其价值?当此自定义类型中需要进行深拷贝时就有其价值。

3.c++98和c++11用法效率比较:

int main()
{
    //c++98
    vector<int> ret;
    func(ret);

    //c++11
    vector<int> ret=func();
}

如上,都想给vector中存放结果,对于c++98来说,只有如上这样做才能提高效率,而c++直接接收返回值即可,因为stl容器基本上都实现了移动构造移动赋值

4.stl中的插入等都加入了右值版本

3.插入操作的右值引用版本

我们就以list为例

首先给节点的构造函数加一个右值版本,不过库里面参数是直接写成了 T&& data,没有加const和缺省值,然后先修改push_back和insert,都在原始的基础上添加一个右值版本

然后尾插调试测试一下:

发现进入push_back时进入的是右值版本,但是进入insert时进入到是左值版本!!因为前面说过,右值被引用后,右值引用就是左值了!!!。那怎么办??可以加上move

那么凡是涉及到右值传递的,传递完后都应该加上move,如下:

还有一个地方需要注意:

这里data的构建!!data可能是内置类型,也可能是自定义类型,也可能是容器,所以它也应该加上move,只要它对应的类中写了移动构造。就能提高效率

4.右值引用使用注意

当用右值引用去构造对象后,右值引用就不存在了,如下例子:

s1没打印出来。为啥呢?因为移动构造其实就是资源转移,它把s1的资源转移给了s3,所以s1就被置空了

三.完美转发

1.万能引用

在普通函数中&&只能是接收右值引用。但是在模板中,&&表示万能引用,也就是说,当参数是左值时,它就是左值引用,当参数是右值时,他就是右值引用。

2.完美转发

void func(int& t)
{
	cout << "左值引用" << endl;
}
void func(const int& t)
{
	cout << "const左值引用" << endl;
}
void func(int&& t)
{
	cout << "右值引用" << endl;
}
void func(const int&& t)
{
	cout << "const右值引用" << endl;
}
template<class T>
void perfectForward(T&& t)
{
	func(t);
}
int main()
{
	int a = 10;
	const int b = 20;
	perfectForward(a);
	perfectForward(b);
	perfectForward(move(a));
	perfectForward(move(b));

}

按照上面万能转发的规则,程序的结果应该是前俩个是左值后俩个是右值,但结果如下:

这是因为右值被引用后就变回了左值。那么如何保持右值的属性呢?就可以用到完美转发:

完美转发能够保证变量在传递过程中的属性,这次结果就是想要的了:

上面对push_back的实现就可以不再使用move而去使用forward<T>

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

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

相关文章

python检测keycloak证书连接报错问题

最近一直被keycloak的证书问题困扰了很久&#xff0c;老是提示ssl安全连接&#xff0c;由于不会java,只好硬着头皮用python测试。 我这里的证书是自己签注的证书&#xff0c;导入系统的是CA根证书。 from keycloak import KeycloakOpenID# 1. 配置 Keycloak 客户端 keycloak_o…

电子画册3D翻页电子版是如何制作

​随着科技的发展&#xff0c;传统的纸质画册逐渐被电子画册所取代。电子画册3D翻页电子版以其独特的交互方式和丰富的视觉体验&#xff0c;受到了越来越多人的喜爱。让我来教你怎么制作吧。 1.要制作电子杂志,首先需要选择一款适合自己的软件。比如FLBOOK在线制作电子杂志平台…

信息收集常用指令

目的 本文主要是记录一些在信息搜集时&#xff0c;常用的提高搜索效率的命令。 后续会继续记录一些用到的更多指令和方法&#xff0c;慢慢更新。 1、inurl “inurl:xxx”是指查找url中包含xxx的网页。 URL&#xff1a;统一资源定位符。统一资源定位系统。可以说包含域名&am…

ThreaLocal

1.概述 ThreadLoca称线程局部变量&#xff0c;用于在线程中保存数据&#xff0c;保存的数据仅属于当前线程(即对其他线程而言&#xff0c;该变量是当前线程独有的变量) threadLocal利用Thread中的ThreadLocalMap来进行数据存储 2.常用方法 存储数据至当前线程ThreadLocalMap中…

无监督神经组合优化的扩散模型框架

文章目录 Abstract1. Introduction2. Problem Description2.1 无监督神经组合优化3. Neural Probabilistic Optimization Objective for Approximate Likelihood Models3.1 具有联合变分上界的训练扩散模型Abstract 从离散集合的不可处理分布中进行采样,而不依赖相应的训练数据…

OpenAI o1解决了Quiet-STaR的挑战吗?(下)

随着OpenAI o1近期的发布&#xff0c;业界讨论o1关联论文最多之一可能是早前这篇斯坦福大学和Notbad AI Inc的研究人员开发的Quiet-STaR&#xff0c;即让AI学会先安静的“思考”再“说话” &#xff0c;回想自己一年前对于这一领域的思考和探索&#xff0c;当初也将这篇论文进行…

初学者蒙语学习,使用什么翻译软件学习更快?

为了加快蒙古语的学习&#xff0c;初学者应该从基础语法和词汇入手&#xff0c;利用语言学习应用进行系统学习&#xff0c;并通过音频和视频材料提高听力。语言交换和参加课程可以提供实践机会&#xff0c;而使用闪卡和文化沉浸有助于记忆词汇和理解语言背景。定期复习和设定学…

聊天组件 Vue3-beautiful-chat 插槽

前言 Vue3-beautiful-chat 组件有四个插槽可以定制 一、user-avatar(头像) 首先是头像插槽,我们可以直接在 <beautiful-chat></beautiful-chat> 中间使用; 作用: 我们可以在用户头像上添加自定义样式,比如添加节日边框、可以使用首字母作为头像。。。 …

小阿轩yx-通过state模块定义主机状态

小阿轩yx-通过state模块定义主机状态 前言 前面学习了远程执行模块&#xff0c;这些模块的执行类似语段 shell 脚本&#xff0c;每次执行都会触发一次相同的功能&#xff0c;在大量的 minion 上运行远程命令当然是重要的&#xff0c;但是对于 minion 的环境控制&#xff0c;使…

Python 二级考试

易错点 定义学生关系模式如下&#xff1a;Student &#xff08;S#&#xff0c; Sn&#xff0c; Ssex&#xff0c;class&#xff0c;monitorS#&#xff09;&#xff08;其属性分别为学号、学生名、性别、班级和班长学号&#xff09; 在关系模式中&#xff0c;如果Y -> X&…

超详细!百分百安装成功pytorch,建议收藏

文章目录 一、Anaconda安装1.1下载anaconda1.2配置Anaconda环境1.3验证anaconda是否安装成功 二、查看电脑显卡三、更新显卡驱动3.1下载驱动3.2、查看显卡驱动版本 四、cuda安装4.1CUDA下载4.2CUDA环境配置4.3验证CUDA是否安装成功 五、安装pytorch4.1下载pytorch5.2验证pytorc…

计算机专业的就业方向

计算机专业的就业方向 亲爱的新生们&#xff0c;欢迎你们踏上计算机科学的旅程&#xff01;作为一名计算机专业的学生&#xff0c;你们即将进入一个充满无限可能的领域。今天&#xff0c;我将为大家介绍计算机专业的一些主要就业方向&#xff0c;帮助你们了解未来的职业选择。…

备忘录应用哪些值得推荐?优秀的桌面备忘录下载

在我们的日常生活和工作中&#xff0c;备忘录是一款常用的记录软件&#xff0c;它为我们提供了极大的便利&#xff0c;让我们可以随时记录下重要的信息、灵感和待办事项。然而&#xff0c;如今网上的备忘录软件琳琅满目&#xff0c;究竟哪一款才是真正优秀的呢&#xff1f; 在…

分步指南:如何使用 ChatGPT 撰写文献综述

撰写文献综述对于研究人员和学生来说,往往是一项既耗时又复杂的任务。这一过程不仅要求对所选主题的现有研究进行全面的了解和掌握,还需要学术严谨性。然而,随着像 ChatGPT 这样的高级语言模型的广泛应用,撰写文献综述的过程变得更加高效和简化。通过合理利用 ChatGPT,研究…

分享三款简单好用的文档翻译软件

在平时的工作学习中免不了会碰上需要翻译文件的时候&#xff0c;给大家分享三款简单好用的翻译软件&#xff0c;可以直接翻译整篇的文档&#xff0c;翻译速度快&#xff0c;准确率高&#xff0c;可以大大提高效率。 1.谷歌翻译 这个翻译软件支持在线翻译&#xff0c;也可以翻…

华为 HCIP-Datacom H12-821 题库 (25)

&#x1f423;博客最下方微信公众号回复题库,领取题库和教学资源 &#x1f424;诚挚欢迎IT交流有兴趣的公众号回复交流群 &#x1f998;公众号会持续更新网络小知识&#x1f63c; 1.以下哪些事件会导致 IS-IS 产生一个新的 LSP? A、邻接 Up 或Down B、引入的 IP 路由发送变…

康佳集团的多元化战略:创新还是负担?

2023年&#xff0c;康佳集团豪赌“一轴两轮三驱动”战略&#xff0c;企图以消费电子和半导体为马&#xff0c;来驱动业绩的快车&#xff0c;但2024年的半年报如同一盆冷水&#xff0c;让所有期望化为泡影。 财报显示&#xff0c;康佳上半年营业总收入只有54.13亿元&#xff0c…

传输大咖44 | 云计算企业大数据迁移如何更安全高效?

在云计算时代&#xff0c;数据已成为企业最宝贵的资产之一。对于依赖云服务的企业和组织来说&#xff0c;大数据迁移是实现业务扩展和优化的关键步骤。然而&#xff0c;这一过程并非没有挑战。传统的文件传输方式在安全性、稳定性和速度上往往无法满足云计算企业的需求。本文将…

ORCA-3D避障代码和原理解析

二维ORCA原理参考&#xff1a; https://zhuanlan.zhihu.com/p/669426124 ORCA原理图解代码解释 1. 找到避障速度增量 u 碰撞处理分为三种情况&#xff1a; &#xff08;1&#xff09;没有发生碰撞&#xff0c;且相对速度落在小圆里 &#xff08;2&#xff09;没有发生碰撞&a…

CANopen从站为什么总不上传PDO报文?

在CANopen网络中无法获取从站的TPDO数据&#xff1f;本文将为您解析可能的原因及解决方案。通过检查TPDO的通信参数和传输类型&#xff0c;确保主站与从站的数据同步&#xff0c;快速定位问题所在。 如果你的CANopen网络中已经确保接线和波特率都没有问题&#xff0c;但无论主站…