C++11 右值引用

来源:互联网 发布:防伪税控开票数据导出 编辑:程序博客网 时间:2024/06/16 09:20
#include  "stdafx.h"
#include<iostream>  
using namespace std;
 
 /*
左值和右值的一个最常见的误解是:等号左边的就是左值,等号右边的就是右值。
左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,
右值是指表达式结束时就不再存在的临时对象。一个区分左值与右值的便捷方法是:
看能不能对表达式取地址,如果能,则为左值,否则为右值。
 
int a是持久对象(可以对其取地址),是左值;
(a+1)是临时对象(不可以对其取地址), 是右值;
 注: 变量a被创建后,在它的作用域内是一直存在的。如此一来,它的引用是有存在意义的。
而a+1不是一个对象,在运算中临时存在于寄存器中,而寄存器中的值是时刻被刷新的,创建a+1的引用显得没有任何意义。
为了成功的使用类似于a+1这种右值的引用 ,C++新标准提出了区别于以往的引用-右值引用。

a++ 是先取出持久对象a的一份拷贝,再使持久对象a的值加1,最后返回那份拷贝,
而那份拷贝是临时对象(不可以对其取地址),故其是右值;

++a则是使持久对象a的值加1,并返回那个持久对象a本身(可以对其取地址),故其是左值;

 int  * p 是持久对象(可以对其取地址),是左值;

arr[0]调用了重载的[]操作符,而[]操作符返回的是一个int &,为持久对象(可以对其取地址),是左值;
 
100和string("hello")是临时对象(不可以对其取地址),是右值;

string str= "hello ";   是持久对象(可以对其取地址),是左值;

int& foo(); foo() = 42; //  foo()是左值

str1+str2是调用了+操作符,而+操作符返回的是一个string(不可以对其取地址),故其为右值;

const  int &m = 1   (   int &m = 1是错的  ) ;  是一个常量引用,引用到一个右值,但引用本身是一个持久对象
(可以对其取地址),为左值。

C++ 11中引入的右值引用正好可用于标识一个非常量右值。
C++ 11中用&表示左值引用,用&&表示右值引用 
右值引用,是对临时对象的一种引用,它是在初始化时完成引用的,但是右值引用不代表引用临时对象后
就不能改变右值引用所引用对象的值,仍然可以在初始化后改变临时对象的值。


在C++旧标准中,我们可以引用a,但却无法引用a+1,这是为什么呢?
*/





void fun(int  & x)// 左值引用重载
{
cout << " &     " << x  <<endl;
}
void fun(int && x) // 右值引用重载
{
cout << " &&   " << x << endl;
}
  


int main()
{


int a = 22;


//  int  &b = 100;//错误 ,100 为右值。


const   int  &b1 = 100;//  加const之后 正确,最大限度就是用常量引用绑定一个右值


int &b2 = a;  //正确, a的引用


int  && b3 = 100;//正确, b3为右值引用 , b3引用100的临时空间
cout <<&b3<<","<< b3 << endl;
b3 = a; 
cout << b3 << endl;


// int && b4 = a; //错误 , a为左值。


int  && b4 = a++; //正确 , a++是右值。 




fun(a);
fun(  a+100 ); //调用了右值




class A
{};
A  && c = A();//正确,临时对象 A()






}
0 0
原创粉丝点击