左右值及其引用详解

文章目录


一、左值和右值

一段内存有两个基本的属性:内存的地址和内存中存储的数据。而左值(L-values)和右值(R-values)就体现了这两种感觉。从字面意思来看,左值就是=左边的值,右值就是=右边的值。这也可以浅显的得出,C++中的表达式不是左值就是右值,绝无出二者之外,但表达式可以同时具有左值属性和右值属性。左值表达式的特点是有持久性,可以取地址,可以被我们赋值,也就是说具有可以被我们访问的存储单元,例如变量、对象成员等。而右值的特点是通常的临时性,无法被我们修改。列如常量、可以是不占据内存的临时变量或字面值,可以是不具有写入权限的空间实体等。因此,我们可以用赋值运算符(=),取地址符(&)来判断表达式是左值还是右值,如果可以使用就是左值,否则为右值。同时,左值表达式的整体应是一个对象,但表达式整体是一个对象的表达式不一定是个左值。

二、引用

在C++11引入了右值引用的概念之后,我们可以将引用分为三种了,也就是左值引用和右值引用,以及常量引用(其实也是左值引用的一种)。

右值引用就是绑定到右值上的引用。右值引用可以说是针对临时对象的,与左值引用相对。

右值引用的主要作用是消除两个对象间不必要的拷贝,移动含有不能共享资源的类对象,提升效率。

右值引用使用 && 符。使用&&绑定右值的右值引用是可以取地址和赋值的,也就是说右值引用是左值。

cpp 复制代码
int &&ra=1;//ra为右值引用,但为左值
ra=3;//赋值操作
int *b=&la;//取地址操作
//以上操作都是正确的

引用并不可以像指针那样可以指向一个空指针,并没有空引用的概念,所以引用在定义时必须进行初始化。常量引用是左值引用中的极其特殊的一部分,因为常量引用可以绑定到右值上。当我们将一个左值绑定到常量引用的时候,编译器会生成一个临时变量去接收左值的值,再将其绑定到常量引用上,这样就实现了常量引用绑定右值。总结一般来说,左值引用只能绑定左值,右值引用只能绑定右值,常量引用都可以绑。(这里左值引用指非常量左值引用)。

返回左值引用的函数以及赋值、下标和前值递增递减运算符(前++,前--)都是返回左值的例子。返回非引用类型的函数以及算数、关系、位和后置递增递减运算符(后++,后--)都是返回右值的例子。前++/--实际上是将内存中的数据减/加1,而后++/--则会产生产生一个临时变量用于接表达式的值并减/加1,当使用完后,临时变量就会销毁。

对于左值引用和右值引用,我的理解是,左值引用是内存地址和内存内容的双重绑定,而右值引用更像简单的绑定内容,或者更干脆的将临时对象起个名字,将其变为一片持久的内存地址(这种给人一种二次利用的感觉,就好像是房东将即将到期出租房改为商品房把房产证转让了)。

三、std::move函数

我感觉这里move的意思是从左边移动到右边吧,因为std::move的作用就是把左值强制转换为右值。如果我们再用一个右值引用来接std::move返回的右值,那么我们实现了对象权限或者状态之间的转换,这种转换并不会开辟新的内存或者调用拷贝操作,是极其高效的。一般来说,我们不会对还回再次使用的对象使用std::move操作,也不会滥用它。

cpp 复制代码
int &&a=10;
int &&b=std::move(a);
相关推荐
John_ToDebug19 小时前
浏览器扩展延迟加载优化实战:如何让浏览器启动速度提升50%
c++·chrome·windows
是娇娇公主~19 小时前
C++ 中 std::deque 的原理?它内部是如何实现的?
开发语言·c++·stl
SuperEugene20 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
AI成长日志20 小时前
【datawhale】hello agents开源课程学习记录第5章 智能体应用实践:低代码平台构建指南
学习·低代码·开源
xuxie9921 小时前
N11 ARM-irq
java·开发语言
GHL28427109021 小时前
RAG相关问题整理学习
学习·ai
wefly201721 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509801 天前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默1 天前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
csdn_aspnet1 天前
C/C++ 两个凸多边形之间的切线(Tangents between two Convex Polygons)
c语言·c++·算法