左值和右值

左值和右值

1、什么是左值和右值?

  • 左值
    左值是可以标识并且在内存中有位置的。通俗表达就是,能取到地址的就是左值。
  • 右值
    右值是临时的、无法取地址的。

也就是说,能取到地址的就是左值,反之就是右值。

下面这个例子,test就是左值,因为我们可以使用&test取到test的内存地址,而9就是一个右值,因为我们取不到地址。
那么,test2以及GetValue2(test+test2)中的“test+test2”是左值还是右值呢?

int GetValue()
{
	return 10;//右值
}
void GetValue2(int value)
{
	std::cout << "the value is : " << value << std::endl;
}
int main(int argc, char* argv[])
{
	int test = 9;//test是左值,9是右值
	int test2=10;
	GetValue2(test+test2);
}

上面的例子中test2显然是左值,因为可以取到地址。而GetValue2(test+test2)中的“test+test2”则是右值,因为它是临时变量,我们取不到地址。

2、左值引用和右值引用

上面例子的 GetValue2(int value)既接受左值输入,又接受右值输入。C++既然对左值和右值做了区分,那么肯定二者有各自的应用场景。那么,有没有只能接受左值或者只能接受右值的写法呢?这么做的意义又是什么?二者各自的应用场景又是什么呢?别急,我们一一道来。

GetValue2(int value)既接受左值输入又接受右值输入,本质上是值传递,也就是无论是左值还是右值,都会生成一个副本传递给函数。如果不是副本传递,而是直接操作实参,那就只能使用指针或者引用了。由此,C++就引入了左值引用和右值引用。

2.1 写法

左值引用使用“&”标记,右值引用使用“&&”标记。见下面的示例。

//右值引用,只能接受右值输入
void SetValue1(int&& value)
{
	std::cout << "the R_value is : " << value << std::endl;
}
//左值引用,只能接受左值输入
void SetValue1(int& value)
{
	std::cout << "the L_value is : " << value << std::endl;
}

如果我们强行将一个左值赋值给右值引用,就会出现下图的错误。
在这里插入图片描述
而如果强行将一个右值赋值给左值引用,就会出现下图的错误。
在这里插入图片描述
那么如果我们既想使用引用传参的形式,又想既接受左值又接受右值呢?
——用const,写法如下例所示,
很多程序使用const引用,一是不能改变引用的内容,二是为了兼容左值和右值

//即接受右值又接受左值
void SetValue3(const int& value)
{
	std::cout << "the value is : " << value << std::endl;
}
2.2 意义与使用场景

C++11之前的引用都是左值引用的形式。为了提高内存管理效率,在C++11中引入了右值引用,主要用于实现移动语义和完美转发。

  • 移动语义
    允许资源的所有权从一个对象转移到另一个对象,而无需进行深拷贝。(详细说明可看我另一篇博客:https://blog.csdn.net/Tulip_Alice/article/details/135606425)
  • 完美转发
    先说说什么是转发,转发指的就是函数之间的参数传递(例如,函数f1接收了一个参数a,然后又把这个参数a传递给了其函数体内调用的另一个函数f2)。
    完美转发就是在函数之间传递参数的过程中,参数在传递后的属性保持不变(左值仍是左值,右值仍是右值)
  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值