左值引用和右值引用

转载地址:https://blog.csdn.net/qianyayun19921028/article/details/80875002
https://www.cnblogs.com/xiangtingshen/p/10366697.html
在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。一切常数、字符和字符串都是右值举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。

左值一定在内存中,右值有可能在内存中也有可能在寄存器中

int a=5int b=a;//此时a在内存中



int a=5int b=a+1;//此时a+1在寄存器中

int *p=&a;//此时&a在寄存器中

引用:就是取别名 ,引用不可以重定义

void main()
{
int num1(5);
int num2(10);
int *pnum(&num1);//将num1的地址传递给pnum
int * &rnum = pnum;//rnum是pnum的别名
rnum = &num2;//rnum和pnum指向同一片内存  改变了rnum就相当于改变了pnum
cout << *pnum << endl;


system("pause");

}


void main()
{
int num1(5);
int num2(10);

int * &rnum = &num1;//这是不允许的  无法从“int *”转换为“int *&”

system("pause");
}

int * &rnum是一个引用,引用的类型是指针变量。
从以上两个例子可以看出int *pnum(&num1); int * &rnum = pnum;通过一个指针在进行取别名是可以的,因为此时指针在内存中,而直接int * &rnum = &num1;取别名是不行的,&num1在寄存器中。在内存中的值是可以直接取别名的也就是引用。但是在寄存器中的值在不可以直接被引用的。其实这就是所谓的左值引用和右值引用。

在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。
在内存中的变量才是可以取地址的,而在寄存器中的变量是不可以取地址的。对于一个不能取地址的表达式或者值是无法直接引用的。所以int * &rnum = &num1;编译不通过。
讲了以上那么多,左值引用就是对一个左值进行引用的类型。右值引用就是对一个右值进行引用的类型。右值引用和左值引用都是属于引用类型。无论是声明一个左值引用还是右值引用,都必须立即进行初始化。而其原因可以理解为是引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。
————————————————————————————————————————
左值引用通常也不能绑定到右值,但常量左值引用是个“万能”的引用类型。它可以接受非常量左值、常量左值、右值对其进行初始化。不过常量左值所引用的右值在它的“余生”中只能是只读的。相对地,非常量左值只能接受非常量左值对其进行初始化。

int &a = 2;       # 左值引用绑定到右值,编译失败
 
int b = 2;        # 非常量左值
const int &c = b; # 常量左值引用绑定到非常量左值,编译通过
const int d = 2;  # 常量左值
const int &e = c; # 常量左值引用绑定到常量左值,编译通过
const int &b =2;  # 常量左值引用绑定到右值,编程通过

在C++11之前,右值是不能进行引用的。右值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值,右值引用实现了移动语义和完美转发,主要目的有以下两个方面:
  1. 消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。
  2. 能够更简洁明确地定义泛型函数。

int a;
int &&r1 = c;             # 编译失败
int &&r2 = std::move(a);  # 编译通过
int &&r3 = 1;			  # 编译通过

右值引用的方法就是int * &&rnum = &num1; 。
&代表左值引用,&&代表右值引用。

下面来说一下为什么要右值引用,右值引用在你需要使用寄存器中的值的时候可以进行右值引用。寄存器的刷新速度很快,没有右值引用的话就需要将寄存器中的值拷贝到内存中,在进行使用,这是很浪费时间的。

int getdata(int &&num)
{
cout << num;
num += 10;
return num;
}


void main()
{
int a = 5;
cout << getdata(a + 1) << endl;
}

如上 int getdata(int &&num)就是对右值进行引用。 getdata(a + 1) 中a+1是右值在寄存器中,我们是不可以直接对他进行操作的,如果要操作得将其拷贝到内存中,如果是一个非常大的数据这种拷贝就会很占用内存,如果直接用右值引用就可以直接对其进行操作。从而节约内存。

将右值转化为左值 直接新建变量然后赋值就可以了

int b=a+1;将a+1这个右值转变为左值了

move(a)将a这个左值转变为了右值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值