C++引用总结

什么是引用?

引用是在C++2.0版本引入的。

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量一直绑定在一起共用同一块内存空间。


一般情况,引用具有以下性质。

1,引用不是一个变量,只是一个已存在变量的别名。

int a = 10;
int& ra = a;//ra是a的引用
//sizeof(ra) == sizeof(a)
ra = 20;//对ra操作赋值,则相当于对a赋值。

2,可以有多个引用与同一个已存在变量绑定到一起。

int a = 10;
int& ra1 = a;
int& ra2 = a;
int& ra3 = a;//ra1,ra2,ra3都是a的别名

3,引用不是一个变量,不能定义引用的引用,不能定义指向引用的指针

int& rra = ra;//错误。
int *p = ra;//错误

4,由于要和某一变量绑定,所以引用必须初始化。

int& ra;// error C2530: “ra”: 必须初始化引用

5,引用的类型要和与之绑定的变量类型严格匹配。

int a = 10;
float& fa = a;//error C2440: “初始化”: 无法从“int”转换为“float &”

6,引用绑定后,将一直与变量绑定在一起,所以引用不能再重新绑定到另一变量。

int a = 10;
int b = 20;
int& ra = a;
&ra = b;//错误,无法重新绑定

注:数组可以引用,只是写法和一般不同

	int b[10] = {0};
	int (&rb)[10] = b;


Const的引用

引用除了可以和变量绑定外,还可以绑定到const对象上,称之为“对常量的引用”。所以,对常量的引用,不能修改它所绑定的对象。

提示:常量引用是其实对const的引用,因为引用本身不是一个对象。

const int a = 10;
const int& ra = a;//对const修饰的变量a的引用
ra = 20;//错误,ra试图修改与它绑定对象的值。
int& ra2 = a;//错误,试图让一个非常量引用绑定到一个常量上。

前面提到,引用的类型必须和其绑定对象的类型一致,但是,C++允许一个常量引用绑定到非常量的对象、字面值,甚至是一个表达式。

int a = 10;
const int b = 20;

const int& ra = a;//允许将const int&绑定到一个普通int对象上
const int& rb = b;//rb是一个常量引用。

const int& r1 = ra*rb;//r1是一个常量引用
int& r2 = r1*3;//错误:r2是一个非常量引用。
为什么,会出现上面的特例呢。

观察下列代码,判断编译器对于i1和i2的理解。

double d = 20.0;
int& i1 = d;//error C2440: “初始化”: 无法从“double”转换为“int &”
const int& i2 = d;//warning C4244: “初始化”: 从“double”转换到“const int”,可能丢失数据
分析:

第一句话,错误提示:无法从double转换为int &,我们都理解,是因为类型不同。

但是第二句话,不是错误提示:无法从double转换为const int &呢?确实警告double转换为const int有数据丢失。

说明,编译器帮我做了隐式转化,将double转化为const int,然后等号左右两类型相同,自然通过编译。

转化过程:这里编译器对代码进行插手了,为了确保让i2绑定到一个整型,编译器隐式转化,用double类型d 生成了一个临时对象const int,(临时对象具有常性)。将r2指向了临时对象。

对const的引用可能引用一个非const对象。此时可以通过特殊手段改变const引用的值。

	int a = 10;
	const int& ra1 = a;//常量引用
	int& ra2 = a;//非常量引用

	ra1 = 20;//错误,无法修改
	ra2 = 20;//正确,可以修改

引用作为参数或返回值

对引用的操作就是对其绑定对象的操作,所以引用可以作为参数或返回值。

引用作为参数和返回值具有和指针一样的效率但是比指针更安全,操作更方便。

原因下面描述。


引用和指针的区别

想到搞清楚引用与指针的区别,要先看看编译器是如何看待他俩的工作原理

#include <iostream>

int main()
{
	int a = 10;
	int& ra = a;
	int* pa = &a;

	return 0;
}
看其汇编

	int& ra = a;
012D13C5  lea         eax,[a] 
012D13C8  mov         dword ptr [ra],eax 
	int* pa = &a;
012D13CB  lea         eax,[a] 
012D13CE  mov         dword ptr [pa],eax 
可以发现,编译器对指针和引用的看待方式相同,即引用被当做指针来看待。

所以:我们一般将int& ra = a与nt *const ra = a;是等效的。

虽然两者在底层上的实现是相同的,都是当做指针来使用。

但是,在语言层面两者还是有很大的不同。

根据对引用的描述和指针的概念比较可以的出以下结论

1、引用在定义时必须初始化,指针没有要求。

2、一旦一个引用被初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型对象

3、没有NULL引用,但有NULL指针。

4、在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数。

5、引用自加改变变量的内容,指针自加改变了指针指向

6、有多级指针,但是没有多级引用

7、引用比指针使用起来相对更安全





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值