
引用变量是一个别名,通过它可以 *** 作其所引用的变量
特点- 引用必须要进行初始化,不能单独存在
- 引用一经绑定之后,不能再改变其指向
- 引用底层实现就是指针,它是一个受到限制的指针
- 引用的使用跟普通的变量是一致的。
- 指针是可以单独存在,也不一定要进行初始化
- 指针是可以改变指向的,比引用更灵活,但同时风险更高
- 指针需要进行间接访问,才能得到相应的数据
- 不能返回局部变量的引用
- 不要轻易返回堆空间变量的引用,除非你有了内存回收的策略
相当于变量的别名,可以直接修改引用绑定的变量
**引用 约等于 const * **
左值与右值引用 左值与右值左值
- 可以取地址的,有名字的,非临时的就是左值
- 非匿名对象,函数返回的引用,const对象等都是左值
- 用户创建的,通过作用域规则可知其生存期的,就是左值(包括函数返回的局部变量的引用以及const对象)
右值
- 不能取地址的,没有名字的,临时的就是右值 立即数,函数返回的值等都是右值
- 从本质上理解右值,创建和销毁由编译器幕后控制,程序员只能确保在本行代码有效的,就是右值(包括立即数)
代码实现
int a = 10;
int &b = a; //定义一个左值引用变量
b = 20; //通过左值引用修改引用内存的值
左值引用在汇编层面其实和普通的指针是一样的;定义引用变量必须初始化,因为引用其实就是一个别名,需要告诉编译器定义的是谁的引用。
int & var = 10
上述代码无法编译通过,因为10无法进行取地址 *** 作,无法对一个立即数取地址,因为立即数并没有在内存中存储,而是存储在寄存器中,可以通过以下方法进行引用
const int & var = 10;
使用常引用来引用常量数字10,因为此刻内存上产生了临时变量保存了10, 这个临时变量是可以进行取地址 *** 作的,因此var引用的其实是这个临时变量相当于以下 *** 作
代码实现
const int temp = 10;
const int & var = temp;
左值引用要求右边的值必须能够取地址,如果无法取地址,可以用常饮用,但使用常饮用后,我们只能通过引用来读取数据,无法去修改数据,因为其被const修饰成常量引用了。
右值引用右值往往是没有名称的,因此要使用它只能借助引用的方式。这就产生一个问题,实际开发中我们可能需要对右值进行修改(实现移动语义时就需要),显然左值引用的方式是行不通的。为此,C++11 标准新引入了另一种引用方式,称为右值引用,用 “&&” 表示。
定义右值引用的格式
类型名 && 引用名 = 右值表达式
//例
int && var = 10;
在汇编层面右值引用做的事情与常引用是相同的,即产生临时量来存储常量。唯一的区别在于右值引用可以进行读写 *** 作,而常引用只能进行读 *** 作
右值引用的存在并不是为了取代左值引用,而是利用右值(特别是临时对象)的构造来减少对象构造和析构 *** 作以达到提高效率的目的
右值引用的使用和声明左值引用一样,右值引用也必须立即进行初始化 *** 作,且只能使用右值进行初始化
一
int num = 10;
//int && a = num; //右值引用不能初始化为左值
int && a = 10;
右值引用可以修改右值
二
int && a = 10;
a = 11;
cout << a << endl;
C++语法之定义常量右值引用
const int && a = 10;
这种形式的右值引用并没有实际用处。
一方面,右值引用主要用于移动语义和完美转发,其中前者需要有修改右值的权限
其次,常量右值引用的作用就是引用一个不可修改的右值,这项工作完全可以交给常量左值引用完成
左值引用和右值引用的相互绑定需要遵循以下规则
-
非const左值引用只能绑定到非const左值
-
const左值引用可绑定到const左值、非const左值、const右值、非const右值
-
非const右值引用只能绑定到非const右值,但不适用于函数模板的形参
-
const右值引用可绑定到const右值和非const右值,它没有显示意义(毕竟右值引用的初衷在于移动语义,而移动语义就意味着修改)
非常量左值引用可以引用的值的类型只有非常量左值,常量左值引用非常量左值、常量左值及右值
测试
int num = 10;
int & a = num; //编译成功,非常量左值引用支持引用非常量左值
const int num2 = 100;
int & b = num2; //编译失败,非常量左值引用不支持引用常量左值
int & c= 10; //编译失败,非常量左值引用不支持引用右值
const int & d = num; //编译成功,常量左值引用支持引用非常量左值
const int & e = num2;//编译成功,常量左值引用支持引用常量左值
const int & f = 100; //编译成功,常量左值引用支持引用右值
右值引用不支持引用左值;非常量右值引用可以引用的值的类型只有非常量右值,常量右值引用可以引用非常量右值、常量右值
测试
int num = 10;
const int num2 = 100;
int && a = num; //编译失败,非常量右值引用不支持引用非常量左值
int && b = num2; //编译失败,非常量右值引用不支持引用常量左值
int && c = 10; //编译成功,非常量右值引用支持引用非常量右值
const int && d = num; //编译失败,常量右值引用不支持引用非常量左值
const int && e = num2;//编译失败,常量右值引用不支持引用常量左值
const int && f = 100; //编译成功,常量右值引用支持引用右值
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)