什么是右值引用?

C++98中提出了引用的概念,引用即变量的别名,引用和引用实体共用一块内存空间。此时的引用为左值引用。

C++11中为了提高程序的运行效率,引入了右值引用,右值引用也是别名,但只能对右值进行引用。

什么是右值引用?

C++11中进行了严格的定义:

  1. C语言中的纯右值,如:1 + 2, a + b,100;
  2. 将亡值(传递给你用,用完就析构了)。如:表达式的中间结果、函数按照值的形式返回(临时值、对象)。

C++11认为const修饰的常量是左值。

引用规则:

左值不能引用右值,const左值可以引用右值
右值不能引用左值,但是可以引用move后的左值

右值引用作用

①实现移动语义
②给中间临时变量取别名
③实现完美转发

左值引用和右值引用举例:

int main()
{
	int a = 100;
	int b = 50;
	int& c = a;//左值引用
	int&& d = a + b;//右值引用
	const int& e = a;//const引用左值
	const int& f = d;//const引用右值
	int&& g = move(a);//引用move后的左值
	return 0;
}

为什么C++11会引入右值引用?

如若类中涉及到资源管理,用户必须显式的提供拷贝构造、赋值运算符重载和析构函数,否则编译器将会生成默认的。

对于按照值返回的形式,必须创建一个临时对象,临时对象在创建好之后,则进行了一次拷贝构造,再将该临时对象拷贝构造给接收的对象,则又进行了一次拷贝构造,此时临时对象被销毁。就相当于返回一个临时对象时,会调用两次拷贝构造,对空间而言是一种浪费,程序的效率也会降低,并且临时对象的作用不是很大。

C++11中提出了移动语义的概念:将一个对象中资源移动到另一个对象的方式,可以有效解决该问题。

即:
在这里插入图片描述
则返回的临时对象直接移动构造给接收对象,之后临时对象再进行析构,此时临时对象的资源就会被转移,整个过程中,只需要进行一次堆内存申请,节省了空间,提高了程序的运行效率。

注意:移动构造函数不要设置为const类型的右值引用,否则就会因为资源无法转移而导致移动语义失败;C++11中,编译器会自动为类生成默认生成一个移动构造,该移动构造为浅拷贝,则当类中涉及到资源管理时,用户必须显式定义移动构造。

右值引用引用左值

当需要右值引用引用左值时,可以使用move函数将左值转化为右值,move函数不搬移任何东西,只是就一个左值强转为右值引用,然后实现移动语义。

被转化的左值,其生命周期并没有随着左值的转化而改变,STL中也有另一个move函数,就是将一个范围的元素搬移到另一个位置。

注意:在移动构造时,注意资源的转移

int main()
{
	vector<int> vv{ 1,2,3,4,5,6 };//vv
	vector<int> v(move(vv));//移动构造,此时vv中的资源,会被移动构造到v中,导致vv为空
	return 0;
}
vector<int>&& v(move(vv));//合格的右值引用左值

完美转发

完美转发:目标函数将参数按照传递给转发函数的实际类型转给目标函数,而不产生额外的开销。

即:参数为左值,转发左值,参数为右值,转发右值。左值会调用拷贝语义,右值会调用移动语义。

右值引用会在第二个之后的参数传递过程中属性丢失。C++11通过forward函数来实现完美转发。

总结

①右值引用做参数和做返回值时可减少拷贝次数,本质上利用了移动构造和移动赋值;
②左值引用和右值引用的作用都是减少拷贝,右值引用本质可以认为是弥补左值引用的不足的地方;
③左值引用作用:解决传参过程中,减少返回值的拷贝
做参数时:解决传参时的拷贝;
做返回值:解决返回值的拷贝;
注意:若是返回对象出了作用域就不存在了,则不能返回引用,左值引用就无法解决,故用C++11中右值引用。
④右值引用:解决传参后,内部的存储拷贝问题
做参数:解决内部拷贝次数,不再使用拷贝构造次数,而是移动构造
做返回值:解决外部调用接收返回对象的拷贝,右值引用的移动赋值,减少了拷贝次数。

  • 14
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值