左值和右值

左值和右值

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)。
    完美转发就是在函数之间传递参数的过程中,参数在传递后的属性保持不变(左值仍是左值,右值仍是右值)

相关推荐

  1. c++ 的如何理解

    2024-01-17 20:28:01       40 阅读
  2. C++八股文 003:

    2024-01-17 20:28:01       60 阅读
  3. 引用与引用

    2024-01-17 20:28:01       32 阅读
  4. C++:(引用)&(引用)

    2024-01-17 20:28:01       34 阅读
  5. C++

    2024-01-17 20:28:01       21 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-17 20:28:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-17 20:28:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-17 20:28:01       82 阅读
  4. Python语言-面向对象

    2024-01-17 20:28:01       91 阅读

热门阅读

  1. 并发安全问题:挑战与解决方案

    2024-01-17 20:28:01       53 阅读
  2. 通过浏览器判断是否安装APP

    2024-01-17 20:28:01       50 阅读
  3. Python考试———部分填空题

    2024-01-17 20:28:01       52 阅读
  4. 排序算法-堆排序(含C语言代码示例)

    2024-01-17 20:28:01       68 阅读
  5. Python---爬虫学习(详细注释/优化)

    2024-01-17 20:28:01       56 阅读
  6. 微信小程序怎样给事件传值的

    2024-01-17 20:28:01       54 阅读
  7. 边缘计算发展的瓶颈

    2024-01-17 20:28:01       53 阅读
  8. 实现将信息作为txt,pdf,图片的形式保存到电脑~

    2024-01-17 20:28:01       49 阅读