首页 > 编程语言 >一篇简短的文章把C++左右值关系讲的透透彻彻

一篇简短的文章把C++左右值关系讲的透透彻彻

时间:2024-01-22 12:23:20浏览次数:39  
标签:10 右值 int 左值 C++ 简短 num 透彻 引用

 

目录

 



前言

对于C++的左值和右值相信很多人都没有一个很透彻的了解,之前我也是不懂的时候查阅了好多文章,但是讲完我还是一头雾水,直到我遇到一篇宝藏文章,讲的左值右值的关系以及Move函数的用法是相当的清楚,文章链接在这,话不多说讲解一下
文章链接


C++左值和右值

在 C++ 或者 C 语言中,一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式右值表达式。确切的说 C++ 中左值和右值的概念是从 C 语言继承过来的。

左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、“right value” 的缩写,其实不然。lvalue 是“loactor value”的缩写,可意为存储在内存中、有明确存储地址(可寻址)的数据,而 rvalue 译为 “read value”,指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。

判断某个表达式是左值还是右值的方法:

① 可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。

int a = 5;
5 = a; //错误,5 不能为左值
 
/*
其中a是一个左值,字面值5是一个右值
*/

【注意】 C++中的左值也可以当作右值使用。

int b = 10; // b 是一个左值
a = b; // a、b 都是左值,只不过将 b 可以当做右值使用

② 有名称的、可以获取到存储地址的表达式即为左值;反之则是右值。

上述示例中变量 a、b 是变量名且通过 &a 和 &b 可以获得他们的存储地址,因此 a 和 b 都是左值;反之,字面量 5、10,它们既没有名称,也无法获取其存储地址(字面量通常存储在寄存器中,或者和代码存储在一起),因此 5、10 都是右值。


二、右值引用

1.右值引用的引入

在C++11之前就有引用“&”,但是此种引用有一个缺陷,即正常情况下只能操作 C++ 中的左值,无法对右值添加引用。

int num = 10;
int &b = num; //正确
int &c = 10; //错误


编译器允许我们为 num 左值建立一个引用,但不可以为 10 这个右值建立引用。

“&”表示的引用又称为左值引用。

【注意】虽然 C++98/03 标准不支持为右值建立非常量左值引用,但允许使用常量左值引用操作右值。也就是说,常量左值引用既可以操作左值,也可以操作右值。

int num = 10;
const int &b = num;
const int &c = 10;

右值往往是没有名称的,因此要使用它只能借助引用的方式。这就产生一个问题,实际开发中我们可能需要对右值进行修改(实现移动语义时就需要),显然左值引用的方式是行不通的。

为此,C++11 标准新引入了另一种引用方式,称为右值引用,用 “&&” 表示。

2.右值引用的使用
① 和声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化。

int num = 10;
//int && a = num;  //右值引用不能初始化为左值
int && a = 10;

 

② 右值引用可以修改右值

int && a = 10;
a = 11;
cout << a << endl;   //输出结果为11

③C++语法之词定义常量右值引用

const int&& a = 10;//编译器不会报错

但这种形式的右值引用并没有实际用处。一方面,右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限;其次,常量右值引用的作用就是引用一个不可修改的右值,这项工作完全可以交给常量左值引用完成。

【总结】

①非常量左值引用可以引用的值的类型只有非常量左值,常量左值引用非常量左值、常量左值及右值

	int num = 10;
	int& a = num;	//编译成功,非常量左值引用支持引用非常量左值
	const int num2 = 100;
	int& b = num2;	//编译失败,非常量左值引用不支持引用常量左值
	int& c = 10;	//编译失败,非常量左值引用不支持引用右值
 
	const int& d = num;		//编译成功,常量左值引用支持引用非常量左值
	const int& e = num2;	//编译成功,常量左值引用支持引用常量左值
	const int& f = 100;		//编译成功,常量左值引用支持引用右值

②右值引用不支持引用左值;非常量右值引用可以引用的值的类型只有非常量右值,常量右值引用非常量右值、常量右值

	int num = 10;
	const int num2 = 100;
	int&& a = num;	//编译失败,非常量右值引用不支持引用非常量左值
	int&& b = num2;	//编译失败,非常量右值引用不支持引用常量左值
	int&& c =10;	//编译成功,非常量右值引用支持引用非常量右值
	const int&& d = num;	//编译失败,常量右值引用不支持引用非常量左值
	const int&& e = num2;	//编译失败,常量右值引用不支持引用常量左值
	const int&& f = 100;	//编译成功,常量右值引用支持引用右值

二、右值引用

move()函数的语法格式:

move(arg)
//agr:左值对象,该函数返回arg对象的右值形式
	int num = 10;
	int&& a = std::move(num);  //编译成功
	cout << a << endl;   //输出结果为10;
 

标签:10,右值,int,左值,C++,简短,num,透彻,引用
From: https://www.cnblogs.com/lidabo/p/17979789

相关文章

  • C++类和对象-对象特性(1)
    一.对象的初始化和清理面对对象来源于生活,每一个对象都有初始设置以及对象销毁钱的清理数据的设置二.构造函数和析构函数C++利用上述俩个函数完成对象初始化和清理,这两个函数会被编译器自动调用,完成对象初始化和清理工作,如果我们不提供构造函数和析构函数,编译器会提供(编译器......
  • C++保存数据到txt并导入excel中绘图
    C++运行完成后,有时需要将结果保存在类似txt等的文档中,以便于后续查看或调用。1、保存到txt文件中1#include<fstream>234intmain()5{6doubleDire_angle=45*PI/180;//方向角7doublecenter_x=0.0,center_y=0.0;......
  • 【OpenVINO】基于 OpenVINO C++ API 部署 RT-DETR 模型
     RT-DETR是在DETR模型基础上进行改进的,一种基于DETR架构的实时端到端检测器,它通过使用一系列新的技术和算法,实现了更高效的训练和推理,在前文我们发表了《基于OpenVINO™PythonAPI部署RT-DETR模型|开发者实战》,在该文章中,我们基于OpenVINO™PythonAPI向大家展示......
  • C++命名空间
    C++关键字认识命名空间先看一个例子定义一个rand变量,然后打印,这是没问题的但是如果我们包含头文件stdlib.h呢?就会出现重定义问题这是为什么呢?因为stdlib里面本来就有一个函数叫rand()所以当包含了头文件之后,链接的时候会发现rand重复定义了--这就是命名冲突问题C......
  • C++U6-03-最短路算法2-bellmon-ford算法
    学习目标贝尔曼福特算法、SPFA 可以用来复习的B站视频:1、https://www.bilibili.com/video/BV1RK4y1d7ct?p=3&vd_source=5c960e1ede940bc5cab8ed42c8bdc9372、https://www.bilibili.com/video/BV18a4y1A7gv/?spm_id_from=333.999.0.0 SPFA算法是 Bellman-Ford算法 的队......
  • C++ ——vector数组笔记
     vector是C++标准库中的一个动态数组容器(SequenceContainer),它可以自动管理内存大小,可以在运行时根据需要动态增长或缩小。它是一个非常常用且强大的容器,用于存储一系列元素。可以简单的认为,vector是一个能够放任意类型的动态数组。下面详细介绍 vector 的使用方法......
  • 位运算(c++)
    n的二进制表示第k位是几①先把第k位移到最后一位:n>>k②看个位是几:&1n>>k&1lowbit(x):返回x的最后一位1是多少例如1010--->10,101000--->1000实现:x&-x=x&(~x+1)例:输入一个数组返回数组中每个元素二进制形式中1的个数代码:#include<iostream>using......
  • sed的&操作符+复盘和把经验转化为能力+sed替换关联环境变量+SystemC+C++的struct和cla
    sed的&操作符sed一般是按行操作,如果匹配到,那么匹配到的内容被表示为&。以下是在单行操作中,想要实现在某行数据特定字符前后插入字符的方法。复盘和把经验转化为能力https://www.163.com/dy/article/GEI2Q9EN05429MRP.html通过寻找和尝试新的做事方式,你才能提高自己的能力。......
  • 【C++入门到精通】C++入门 —— 类和对象(了解类和对象)
     目录一、类和对象的历史由来 二、面向过程和面向对象的初步认识三、类1.引子2.类的定义 3.类的访问限定符及封装        ⭕访问限定符 ......
  • C++ const 全局变量跨文件引用,无法解析的外部符号?
    前两天群里有人问了这样一个问题:在a文件中定义了一个全局变量,可以在b文件中引用。但一旦把全局变量改为const之后,就无法在b文件中引用,编译(链接)报错“无法解析的外部符号”,这是为什么?这是因为const修饰的变量默认具有文件作用域,如果想和非const变量一样具有全局作......