c++ 左值、右值、左值引用和右值引用
来源:互联网 发布:天下3 知乎 编辑:程序博客网 时间:2024/06/06 01:11
原文地址:http://blog.csdn.net/cjaymj/article/details/46311045
一、c++中的左值和右值
误区:左值位于等号左边,右值位于等号右边。
C++11中的定义:左值表达式表示的是一个对象的身份(在内存中的位置),而右值表达式表示的是对象的值(内容)。
左值和右值都是针对表达式而言的,左值是持久的,右值是短暂的:左值在表达式结束后仍然存在,右值在表达式结束后会被销毁。
区分左值和右值的方法:看能不能进行取地址操作,若能,则为左值,否则为右值。
注意:在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。
例子:
若有如下定义:
[cpp] view plain copyint a = 10; int b = 20; int *p = &a; vector<int> T; T.push_back(1); string s1 = “Hello”; string s2 = "World"; const int &m =1;
问:
a,b,a+b,a++,++a,p,*p,T[0],100,string(“Hello”),s1,s1+s2,m分别是左值还是右值?
答:
a,b是变量,变量可以看做只有运算对象而没有运算符的表达式,变量表达式都是左值。事实上,变量a,b均是长久的,在生命周期结束才被销毁,且我们能够对a,b进行取地址操作。故a,b均为左值。
a+b是临时变量,在该表达式结束时就被摧毁,且不能对其进行取地址操作,因此a+b为右值。
a++的作用机理是先将a的值拷贝到一个临时变量中,然后将这里临时变量加1,最终返回的是这个临时变量,因此a++为右值。
++a的作用机理是在原数据a上直接加1,最终返回的是原来的那个对象(只不过值加了1),因此++a为左值。
p表示的是指向a的指针,它也是长久的,并且我们能对其进行取地址操作,得到的是指向a的指针的地址。因此p为左值。
*p与a等价,也为左值。
T[0]返回容器T中第一个元素的引用,这是一个int型变量,是长久的,并且能对其进行取地址操作,因此T[0]为左值。
100是个常量,在使用过后就会销毁,并且不能对其进行取地址操作,因此100为右值。
string(“Hello”)与100类似,也是个常量,在使用过后就会销毁,并且不能对其进行取地址操作,因此string(“Hello”)为右值。
s1是string类型的变量,与a,b类似,是长久的,并且可以进行取地址操作。因此s1是左值。
s1+s2与a+b类似,是临时变量,在表达式结束就被摧毁,并且不能对其进行取地址操作。因此s1+s2是右值。
m是一个int类型的const左值引用,但它本身是一个变量表达式,因此m是左值。
二、左值引用和右值引用
左值引用符:&
右值引用符:&&
左值引用不能绑定到右值对象上,右值引用也不能绑定到左值对象上。
由于右值引用只能绑定到右值对象上,而右值对象又是短暂的、即将销毁的。也就是说右值引用有一个重要性质:只能绑定到即将销毁的对象上。
左值、右值引用的几个例子:
[cpp] view plain copyint i = 42;//如前所述,i是一个左值对象 int &r = i;//正确,左值引用绑定到左值对象i int &&rr = i;//错误,右值引用绑定左值对象 int &r2 = i * 42;//错误,如前所述i*42是临时变量,是右值,而&r2是左值引用 int &&rr2 = i * 42;//正确,右值引用绑定右值对象
注意:以上绑定规则有一个例外,如果左值引用是const类型的,则其可以绑定到右值对象上。(只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性, 且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙)
[cpp] view plain copyconst int &r3 = i * 42;//正确,我们可以将一个const的引用绑定到一个右值对象上
对于一个左值,若想使用其右值引用,我们可以用move函数:
[cpp] view plain copyint &&rr3 = std::move(rr1);//正确,显式使用rr1的右值引用
- 左值引用和右值引用
- 引用左值和引用右值
- 左值引用和右值引用
- C++——左值引用和右值引用
- C++——左值引用和右值引用
- 左值、右值、左值引用、右值引用
- 左值、右值、左值引用、右值引用
- 左值 右值 左值引用 右值引用
- 引用,左值,右值
- 左值引用与右值引用
- 左值引用与右值引用
- 左值引用与右值引用
- 左值引用与右值引用
- 右值和左值,右值引用和左值引用
- c++中的左值和右值,左值引用和右值引用
- C++ 左值和右值,左值引用和右值引用
- c++ 左值、右值、左值引用和右值引用
- 左值引用和右值引用的区别
- mybatis实战教程(mybatis in action),mybatis入门到精通
- LwIP裸机ping问题
- Maven下载、安装和配置(一)
- 以Point类为基础,定义一个平面中的Circle类: 1、编写一个无参的构造函数; 2、编写一个有参的构造函数; 3、在主函数中调用无参的构造函数生成圆的实例c1,调用有参的构造函数生成圆的实例c2
- qnx的ssh功能配置,nfs配置,scp配置,telnet配置
- c++ 左值、右值、左值引用和右值引用
- poj 3415 后缀数组+单调栈||后缀自动机
- HID Firmware修改 (HIDtoUARTExample)之二
- angular $http post 方法有些浏览器不支持原因解答
- POJ
- Linux部署Oracle数据库图形界面乱码
- js的promise应用
- HTML跑马灯
- Vue 组件实现表单的双向绑定