C++入门(二): 引用(右值引用)

概述

C++11 在 C++98/03 标准的基础上,对 C++ 语言增添了约 140个新特性。本节要讲的右值引用就是众多新特性中的一个。右值引用是一种新的 C++ 语法,基于右值引用引申出的 2 种 C++ 编程技巧,分别为移动语义完美转发

C++左值和右值

左值:lvalue,loactor value;存储在内存中、有明确存储地址(可寻址)的数据。

右值:rvalue,read value;可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)

一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式。

判断依据(通常):

  1. 可以位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。

    举个例子:

    int a = 5;
    5 = a; //错误, 字面量 5 就是一个右值
    int b = 10; // b 是一个左值
    a = b; // a、b 都是左值,左值 b 也可以当做右值使用
    
  2. 有名称的、可以获取到存储地址的表达式即为左值;反之则是右值。

    以上面定义的变量 a、b 为例,a 和 b 是变量名,且通过 &a 和 &b 可以获得他们的存储地址,因此 a 和 b 都是左值;

    反之,字面量 5、10,它们既没有名称,也无法获取其存储地址(字面量通常存储在寄存器中,或者和代码存储在一起),因此 5、10 都是右值。

注意,以上 2 种判定方法只适用于大部分场景。由于本节主要讲解右值引用,因此这里适可而止,不再对 C++ 左值和右值做深度剖析,感兴趣的读者可自行研究。

C++右值引用

回顾左值引用

C++98/03 标准中加入了左值引用 “&” ,即可以为一个左值建立引用。

int num = 10;
int &b = num; //正确,引用b可以绑定左值
int &c = 10; //错误,引用b不可以绑定右值

同时,C++98/03 标准允许使用常左值引用绑定右值,例如:

int num = 10;
const int &b = num; //常左值引用,绑定左值
const int &c = 10;  //常左值引用,绑定右值

右值引用的必要性

右值往往是没有名称的,因此要使用它只能借助引用的方式。

实际开发中我们可能需要对右值进行修改(实现移动语义时就需要),显然常左值引用的方式不满足需求。

为此,C++11 标准引入了另一种引用方式:右值引用,用 “&&” 表示。

右值引用符号选用现有C++内部已有的符号,且没有与 C++ 98 /03 标准左值引用& 产生冲突

定义和使用

普通右值引用

右值引用也必须立即进行初始化操作,且只能使用右值进行初始化:

int num = 10;
//int &&a = num;  //右值引用不能绑定左值
int && a = 10; 
a = 100; //和常左值引用不同,右值引用可以对右值进行修改
cout << a << endl; //输出 100

常右值引用

const int&& a = 10;//编译器不会报错,但是无实际用途

左值引用和右值引用概览:

-非常量左值常量左值非常量右值常量右值使用场景
非常量左值引用(普通引用)YNNN一般引用的使用
常左值引用(常引用)YYYY常用于类中拷贝构造函数
非常量右值引用(普通右值引用)NNYY移动语义、完美转发
常量右值引用NNYY无实际用途

注:

  • Y表示支持,N表示不支持
  • 左列:引用类型;上行:被绑定的值类型
引用类型 && ra = 被绑定的值a;

为什么常右值引用无实际用处? 右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限;而常右值引用的作用是引用一个不可修改的右值,这项工作完全可以交给常左值引用完成。

将亡值

C++11 标准中对右值做了更细致的划分,分别称为

  • 纯右值(Pure value,简称 pvalue): C++98/03 标准中的右值
  • 将亡值(eXpiring value,简称 xvalue )。指和右值引用相关的表达式(比如某函数返回的 T && 类型的表达式)

对于纯右值和将亡值,都属于右值,有时间可以进一步研究。TODO

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值