现代C++ 理解右值引用

右值引用是C++11引入的新特性,旨在提高程序效率,减少深拷贝操作。它区分左值和右值,左值持久、可寻址,右值短暂、不可寻址。右值引用可以引用右值,常用于移动语义和完美转发。然而,常量右值引用在实际应用中意义不大。

右值引用是C++11中新增新的引用类型。

右值引用只不过是一种新的 C++ 语法。

基于右值引用,引申出的 2 种 C++ 编程技巧:移动语义和完美转发,难以理解。

引入目的 作用好处

引入右值引用的主要目的是提高程序运行效率。有些对象在复制时需要进行深复制(拷贝),深拷贝往往非常耗时。合理使用右值引用可以避免深复制操作。

右值引用通过减少内存的重复申请、拷贝和释放,有效的提高C++程序的性能

 

左值和右值

左值是可寻址的变量;(有名称,能获取其存储地址的实例对象)

右值是不可寻址的字面量,或者表达式求值过程中创建的可寻址的无名临时对象;

无名的临时变量只能在赋值号的右边,而不能出现在赋值号左边。

左值持久性,右值短暂性。

 

左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是“left value”、“right value” 的缩写,其实不然。

lvalue 是“loactor value”的缩写,可意为存储在内存中、有明确存储地址(可寻址)的数据,而 rvalue 译为 "read value",指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。

 

例如,语句

a = b + c,

其中,a在等号左边,有名,可寻址,且生命周期持久,称为左值;

b+c在等号右边,无名,且在该语句结束后即被销毁从而结束生命周期,被称为右值。

 

判断某个表达式是左值还是右值,最常用的有以下 2 种方法。

1) 可位于赋值号(=)左侧的表达式就是左值;只能在赋值号右侧的表达式就是右值。举个例子:

int a = 15;

15 = a; //错误,15 不能为左值

其中,变量 a 就是左值,而字面量 15 是右值。左值也可以当做右值使用,例如:

int b = 20; // b 是左值

a = b; // a、b 都是左值,只不过将 b 当做右值使用

 

2) 有名称的、可以获取到存储地址的表达式为左值;反之是右值。

a 和 b 是变量名,且通过 &a 和 &b 可以获得他们的存储地址,因此 a 和 b 都是左值;而字面量 15、20,它们没有名称,也无法获取其存储地址(字面量通常存储在寄存器中),因此 15、20 都是右值。

 

int &&   rr1 =2;    //正确,字面值常量是右值

int &&   rr2 =rr1;   //错误,表达式rr1是左值!

 

注意: 变量 rr1是左值,我们不能将一个右值引用直接赋值给另一个右值引用类型上。

 

右值引用概念

左值引用

C++98/03 标准中的引用也称为左值引用。

int n= 10;

int &a = n; //正确

int &b = 10;    //错误

如上所示,编译器允许我们为 左值 n建立引用,但不可以为右值10建立引用。

const int &b = num;

const int &c = 10;

旧标准可以使用常量左值引用操作右值, 但是无法修改右值。

右值引用

右值引用,可以引用右值,因而称为“右值引用”。

右值引用可以引用无名的临时变量

右值引用可以修改右值

定义右值引用的格式如下:

类型 && 引用名 = 右值表达式;

例如:

class A{};

A & rl = A();   //错误,无名临时变量 A() 是右值,因此不能初始化左值引用 r1

A && r2 = A();   //正确,因 r2 是右值引用

 

&&的由来

volatile,pointer(*),reference(&),rvalue reference(&&)

使用

声明即进行初始化 

同左值引用一样,右值引用也必须   声明即进行初始化   操作,且只能使用  右值进行初始化,比如:

int num = 10;

//int && a = num;   //右值引用不能被初始化为左值

int && a = 10;

右值引用还可以修改右值

常量左值引用不同的是,右值引用还可以修改右值。例如:

int && a = 10;

a = 50;

cout << a << endl;

程序输出结果为 50。

常量右值引用无用处

C++ 语法上是支持定义常量右值引用的,例如:

const int&&  a = 10;   //编译器不会报错

但这种定义并无用处。

一方面,右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限;

常量右值引用的作用就是引用一个不可修改的右值,这项工作完全可以交给常量左值引用完成。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值