C++11 右值引用

1.识别方法:可对表达式用“&”取值,为左值;否则,为右值。左值可以看作是“对象”,右值可以看作是“值”。

  • 左值和右值的区分
int iVar;
iVar = 5;
//(iVar + 3) = 7;

      解析:iVar是临时变量,&iVar可获取到地址,在寄存器上有确定的存储地址,直到离开作用域时,才销毁!

                &(iVar + 3)获取不到地址,原因是iVar+3在寄存器上也是一个临时值,计算完”iVar + 3 = 7“后便失效,被销毁!

  • 无法将左值引用绑定到右值上,const除外
int iData = 1;
//int& iData = 4;/*不合法,4为右值*/
int& iData1 = iData;/*合法,iData为左值*/
const int& iData2 = 6;/*合法*/

int&& iTemp = 5;/*给右值5具名*/

2.引用折叠

  • 引用规则:右值引用叠加到右值引用依然是右值引用,而其他类型叠加则变为左值引用,且左值或右值独立于它的类型
int&& iTest1 = 2;/*给右值具名*/
//int&& iTest2 = iTest1;/*不可重复具名*/
int&& iTest3 = std::move(iTest1);/*转移具名,2的具名为iTest3*/

iTest1 = 5;/*右值引用可修改*/
int iTest4 = iTest1;/*正常的左值赋值*/

3.类型推导

  • T&&并不一定代表右值,也可能是左值,取决于初始化值的类型.(模板参数举例)

4.作用:优化模板类的入参类型;优化性能,避免深拷贝

  • 模板参数:即可以是左值,也可以是右值。
... ...
template<class T> void Function(T&& x) { auto typeData = x; };

int main()
{
	Function(5);/*右值*/

	int iData = 4;
	Function(iData);/*左值*/
}
  • 深拷贝:即解决了指针悬挂,又避免了深拷贝,特别是一些内存开销大的对象,此法就节省了这一部分的开销。
class CTest
{
private:
	int* m_piPtr;
public:
	CTest() : m_piPtr(new int[2]) {}
	CTest(CTest&& objTest) : m_piPtr(new int[2]){}/*避免指针悬挂*/
	~CTest() { if (nullptr != m_piPtr) delete m_piPtr; m_piPtr = nullptr; }

};
... ...

CTest objTest;
CTest objTest1(std::move(objTest));/*避免深拷贝*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值