左值、左值表达式、左值引用 C++

本文topics

  1. 什么是左值和右值
  2. 什么是左值表达式、右值表达式
  3. 引用的分类

之前学习Java的时候只记得在赋值表达式左边的就是左值,右边的就是右值。这个说法没有错,但今天又在C++中有学习到了关于左右值得概念,在此梳理了一些这些知识点。

左值和右值
左值:左值是一个对象或变量,可以代表着一个固定地址。

int i = 1;//此时,i是个变量,本质和对象一样,是一块内存区域,代表着一个固定的地址。

右值:不能作为左值的都是右值,要么是一个常量,要么就是一个使用一次立即被销毁的临时变量或临时对象,右值没有固定的地址,使用完立即被释放。

int i = 1 ; //1 是一个右值,没有固定地址,虽然它也占内存,但用完就被立即释放

这里必须再提醒一下,左值也可以同时拥有右值属性,但反过来不行。

i =i+5;//这里右边的虽然是个左值,但在这里有右值属性,可以理解为取出i的值和1相加构成一个值为(x+1)的常数(或者说临时变量)

了解了什么是左值和右值,那么哪些地方可以用到呢?
这里举介个常见运用左值的运算符的例子
这些运算符都必须运用左值,无法用右值来运算。这里举几个常见的例子

  • 赋值运算符的左侧必须是左值,这个不用说应该都能理解
  • 取值符号&
int i = 1;
int* ptr = &i;//这里i必须是个左值
  • 容器的下标 [ ]
string s=“daily coding";
cout<
  • ++,- -等。这里有统一方法可以看一个运算符是不是必须用左值。就是看这个运算符能不能操作字面值,如果不可以,就是左值运算符。
3++;//错误,这种直接操作一个字面量显然不行,所以++是必须运用左值的运算符

左值表达式和右值表达式
这个很好理解,一个表达式的求值结果如果是左值,就是左值表达式,否则如果是右值,就是右值表达式

int i = 1;
++i = i+2;
//这里左边++i,是返回一个i的变量,但i的值增加了1,所以是左值表达式
//这里i+1是一个右值表达式 ,因为它是一个存了3的临时地址,赋值给i++后就被释放了。

i++ = i + 2;//错误,因为i++是一个右值表达式,这里可以理解为 有一个临时对象temp=i;i = i+1;然后返回temp,结果就等于 1  =i+1;所以显然不行 

引用分类

  • 左值引用
    即绑定到左值的引用,必须绑定左值
int i = 1;
int &ref = i;//这里ref是绑定了i这个左值的引用
int &ref2 = 3;// 3 是右值,无法绑定
  • 右值引用
    右值引用的作用是给开发者提供一个想要可以绑定临时变量的作用,可以通过右值引用符号“&&” 来实现
int &&i=1;//右值引用可直接引用右值,可以理解为想要给 “ 1 ”一个固定的地址,并给与一个变量名i
i = 3;//可以通过i再赋值
  • Const常量引用,本质上也是左值引用的一种,但区别有二
    一是无法通过这个引用改变引用地址的值,二是它可以间接绑定右值(实际上是绑定了一种左值)
int i = 1;
const int &ref = 1;
i = 10;//错误,无法再赋值 ,因为ref是一个常量引用

const int &ref2 = 100;//可以引用一个右值,本质上是将100转换为一个变量,再将ref2引用到这个变量上

总结

  1. 左值是一个对象或变量,代表一个固定地址,而没有固定地址的临时对象或临时变量既是右值,不能代表一个固定地址
  2. 左值表达式就是一个值为左值的表达式,右值表达式就是值为右值的表达式
  3. 左值引用只能引用左值,右值因为只能引用右值,而const引用就可以同时引用左值和右值(通过临时变量间接引用右值,实际上是左值引用)

你可能感兴趣的:(C++)