左值引用和右值引用

简单总结一下左值、右值、左值引用和右值引用

1. 左值和右值

右值又分为纯右值和将亡值。下面简单列举一下区别:
左值和右值的区别就是是否有固定地址,能够通过取地址符&获得其地址。举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。

  • 左值:够用&取地址的,有具名变量的表达式是左值表达式。例如:函数名和变量名、解引用表达式*p、前置自增/自减等
  • 纯右值:临时变量和不跟对象关联的字面量值。例如:后置自增/自减、非引用返回的临时变量、运算表达式产生的临时变量(a+b、a&b、a<<b、a&&b、a||b、a==b、a>=b、a<b)、原始字面量和lambda表达式等都是纯右值
  • 将亡值:C++11新增的跟右值引用相关的表达式,这样的表达式 通常是将要被移动的对象(移为他用)。将亡值可以理解为通过“盗取”其他变量内存空间的方式获取到的值。例如:返回右值引用T&&的函数返回值、std::move的返回值、转换为T&&的类型转换函数的返回值

下面列举几个容易混淆的:

  1. ++i是左值,i++是右值
  2. 解引用表达式*p是左值,取地址表达式&a是纯右值。&(*p)一定是正确的,而对&a而言,得到的是a的地址,相当于unsigned int型的字面值,所以是纯右值。
  3. a+b、a&&b、a==b都是纯右值
  4. 字符串字面值是左值。不是所有的字面值都是纯右值,字符串字面值是唯一例外。
  5. 具名的右值引用是左值,不具名的右值引用是右值。

一个简单小栗子:

int i = getX();

这行代码会产生两个值,一个左值和一个右值。i是左值,而getX函数返回的临时变量就是右值。

2. 左值引用和右值引用

左值引用:传统的C++中引用被称为左值引用
右值引用:C++11中增加了右值引用,右值引用关联到右值时,右值被存储到特定位置,右值引用指向该特定位置,也就是说,右值虽然无法获取地址,但是右值引用是可以获取地址的,该地址表示临时对象的存储位置
这里主要列举一下右值引用的特点:

  • 通过右值引用的声明,右值又“重获新生”,其生命周期与右值引用类型变量的生命周期一 样长,只要该变量还活着,该右值临时量将会一直存活下去
  • 右值引用独立于左值和右值。意思是右值引用类型的变量可能是左值也可能是右值
  • T&& t在发生自动类型推断的时候,它是左值还是右值取决于它的初始化

注意:常量左值引用是万能类型,可以引用常量左值、非常量左值、常量右值、非常量右值。

template<typename T>
void fun(T&& t) {
	cout << t << endl;
}
int getInt()
{
	return 5;
}
int main() {

	int a = 10;
	int& b = a;  //b是左值引用
	int& c = 10;  //错误,c是左值不能使用右值初始化
	int&& d = 10;  //正确,右值引用用右值初始化
	int&& e = a;  //错误,e是右值引用不能使用左值初始化
	const int& f = a; //正确,左值常引用相当于是万能型,可以用左值初始化
	const int& g = 10;//正确,左值常引用相当于是万能型,可以用右值初始化
	const int&& h = 10; //正确,右值常引用
	const int& aa = h;//正确
	int& i = getInt();  //错误,i是左值引用不能使用临时变量(右值)初始化
	int&& j = getInt();  //正确,函数返回值是右值
	fun(10); //此时fun函数的参数t是右值
	fun(a); //此时fun函数的参数t是左值
	return 0;
}

参考:
https://www.cnblogs.com/qicosmos/p/4283455.html
https://www.cnblogs.com/likaiming/p/9045642.html
https://cloud.tencent.com/developer/article/1543336

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值