您当前的位置: 首页 > 

我什么都布吉岛

暂无认证

  • 3浏览

    0关注

    292博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

左右值属性和引用

我什么都布吉岛 发布时间:2020-09-21 08:53:16 ,浏览量:3

如果用成语来形容左右值,左值就是旷日持久,右值则是昙花一现。

一、左值和右值是表达式属性 1.1 左值和右值的区别

C++的表达式要么是左值的,要么是右值的 。左值和右值的区别在于:

  • 左值可被改写,右值只能改写别人(可写性角度)
  • 左值是持久的,右值是短暂的(生存周期角度)
1.2 运算符与左右值

一些运算符对操作的对象左右值有要求:

  • 赋值语句。(非常量)左值作为左侧操作数,语句返回左值;
int a;
a=3;
(a=4)=5;

赋值表达式是函数,其要求左侧对象是左值(非常量),右侧要则要求为右值。本例中,变量a是非常量的左值,右值字面值常量3右值。返回值表达式属性是左值(这就是为什么赋值语句重载要返回引用)。(a=4)=5;说明了赋值结果是左值。

下面是针对非类类型的汇总:

运算符左侧右侧结果= 赋值LLRL& 取地址UDLR[] 下标LUDL* 解引用UDLRLX++LUDR++XUDLL四则运算LRLR若左右均为L则为L;有一R则为R关系运算LRLRR位运算LRLRR
  • 地址运算符。单输入,要求右侧为左值或函数标识符,返回右值;
void fun(void *){};
&1;//not ok!1是字面值常量为右值
&a;//ok,a是普通变量
&fun;//ok! fun是函数标识符
&fun=3;//not ok!返回的是右值,可这里用作了左值
  • 解引用。右侧要求指针、迭代器。返回值为左值;
  • 下标运算符。string vector 及内置运算符返回值为左值;
  • 递增递减。要求操作对象为左值,返回值也为左值;

小结:左值和右值是表达式的属性。绝大多数运算结果都是左值,取地址则为右值,常见右值有:字面值常量、返回右值的函数、返回右值的运算符(& 后置++ 后置-- ),常见的左值有:非常变量名,返回左值的函数,返回左值的运算符([] 前置++ 前置-- +=)左值是持久的,右值的短暂的,创建即失效。

二、左右值引用 2.1 左值引用

左值引用是一个与左值绑定的引用,不是所有的表达式都能绑定,以下情况不能被绑定:

  • 本身是右值,如字面值
  • 表达式返回右值,如&
  • 类型不严格匹配,如隐式转换
int &a = 4396;//not ok!,字面值常量,右值!
double pi = 3.14;
int &b = pi;//not ok! 发生隐式转换
int &ra = &a;//not ok!取地址返回值为右值!

用户使用左值引用可能会改变引用指向的对象,字面值是存在常量区的,一般不可更改。如果你将这个左值引用声明为常量,那么这个左值引用也可以引用常量。

const int &ra=123;//ok!
2.2 右值引用

右值引用是左值,我们可以通过右值引用对其进行读写,因为右值是短暂的,所以它只能是:

  • 字面值常量
  • 表达式求值过程中临时对象

右值是即将被销毁的、且没有其他用户的对象。在右值引用之前,用户无法对右值资源进行控制、接管。

int num = 10;
//int && a = num;  //右值引用不能初始化为左值
int && a = 10;
a = 100;
cout             
关注
打赏
1658157489
查看更多评论
0.0353s