C++中左值和右值是什么以及存在的理解误区

左值(Lvalue)和右值(Rvalue)的通俗理解是在如下的等式中,右值(Right-value)放在等号右边,左值(Left-value)放在等号左边,这就是左值右值的初步定义。

int a = 1 + 1

但这种方式并不能解释左值和右值的根本含义,并且并不是每一个等式的左边一定是左值,右边一定是右值。其根本的定义和区别不在于能否被赋值,而在与其是否有确定的内存地址。

这里首先要清楚,左值还是右值,针对的是C++中的表达式而言的,C++官方给出的表达式定义为:an operator with its operands, a literal, a variable name, etc.

左值(Lvalue):Location-value,表示可寻址。是保存在内存中,具有确切地址,并能取地址,进行访问,修改等操作的表达式。严格来说,这里定义的左值是pLvalue,也就是pure纯左值。

右值(Rvalue):Read-value,表示可读不可寻址。是保存在内存中,或者寄存器中,不知道也无法获得其确切地址,在得到计算表达式结果后就销毁的临时表达式。严格来说,这里定义的右值是pRvalue,也就是pure纯右值。

右值引用(Xvalue):Expiring value,表示即将过期但还没过期的值。与纯右值和纯左值不同,C++11新出了对右值的引用,取决于如何使用,这种引用既可能是右值,也可能是左值,需要单独考虑。

常见误区
  1. 左值不一定可以修改,常量就是不可修改的,但是它有确定的地址,所以仍然是左值。
int const a = 2;//a是左值,但是a不可以修改
  1. 左值右值和引用,非引用没有关系,左值引用一定是左值,右值引用可能是左值可能是右值。
左值引用右值引用非引用
是左值总是显式声明为变量时
是右值×作为临时变量时
  1. 左值显然可以转换成右值,右值不能转化为左值,但是可以在其销毁前,作为参数转化为左值。
//左值转换为右值
int a = 1;//a是左值
int b = 2;//b是左值
int c = a + b; //这里a和b从左值转换为右值,然后将和(右值)赋值给左值c。

//通过右值获得左值
int array[2] = {1,2}; //array是一个左值
*(array + 1) = 3;//array+1在计算过程中由左值转换为一个临时右值
//该右值被解引用,又从右值转换为一个左值。
  1. 左值引用一般不能用右值初始化,因为如果用右值初始化,相当于将左值绑定在了右值上,那右值就不会被销毁,也就不是右值了(此时编译器通常会提示非常量引用的初始值只能为左值)。但是常量引用显然可以赋右值,因为常量引用不会改变引用的值。当然,右值引用是另一种可以赋右值的引用类型。
int &a = 1;//错误,1是右值,a是左值引用,无法直接初始化
int a = 1; //正确,a是左值不是左值引用,可以被赋值
int const a = 1;//正确,a是常量左值引用,可以链到右值上
int &&a = 1;//正确,这是C++11中的右值引用,a为左值。
  1. 函数的返回值一般是右值,但也可以是左值。
//返回右值的常规函数
int fun(){//函数中a是局部变量,会销毁,所以返回值是右值,只能临时使用。
    int a = 1;
    return a;
}

//返回左值的函数
int &fun(int &a){//函数将输入的引用返回,从始至终都是这个a
    a++;
    return a;
}
//以上函数可以这么用
fun(a) = 4;//因为fun返回左值,所以fun可以被赋值

//错误的返回左值案例
int &fun(){//不要讲局部变量的引用返回,因为返回后局部变量被销毁
    int a = 3;
    return a;
}
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值