前言
对于习惯使用C语言进行开发的同学们,在看到C++中出现的&符号,可能会陷入误区,因为在C语言中&符号表示了取地址符,但其实&在C++中却有着不同的意义与用途——引用。
一:引用的简介
1.1 引用概念
引用就是给已经存在的变量取了一个别名,引用和它引用的变量共用同一块内存空间。
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。
引用的声明方法:类型& 引用变量名 = 引用实体(引用类型必须和引用实体是同种类型)
代码演示:
void TestRef(){
int a = 10;
int& ra = a; // 定义引用类型
printf("%p\n", &a);
printf("%p\n", &ra);
}
1.2 引用特性
引用在使用时要注意以下几点:
(1)引用在定义时必须初始化
(2)一个引用只能有一个实体
(3)一个实体可以有多个引用
注:不能建立数组的引用。数组是一个由若干个元素所组成的集合,无法建立一个数组的别名。
1.3 常引用
代码演示:
void TestConstRef(){
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
}
用const这种方式声明的引用,不能通过引用对实体的值进行修改,从而使引用的实体成为const,达到了引用的安全性。
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。
二:引用的应用
了解了引用的概念之后,下面我们来探索一下引用的实际运用。
2.1 引用做参数
引用的一个重要作用就是作为函数的参数。
使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;
使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;如果传递的是对象,还将调用拷贝构造函数。
因此,当参数传递的数据较大时,用引用传参比用一般变量传递参数的效率和所占空间都好。
2.2 引用做返回值
引用另一个重要的作用就是作为函数的返回值。
用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。
引用作为返回值需要注意:
(1)不能返回局部变量的引用。局部变量出了作用域会销毁,此时引用指向的空间被销毁了,程序将进入未知状态。
(2)不能返回函数内部new分配的内存的引用。被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间就无法释放,造成memory leak。
(3)可以返回类成员的引用,但最好是const。
小结
我们对以上知识进行一个简短的总结:
(1)在引用的使用中,单纯给某个变量取个别名是毫无意义的,引用的目的主要用于在函数参数传递中,解决大块数据或对象的传递效率和空间不如意的问题。
(2)用引用传递函数的参数,能保证参数传递中不产生副本,提高传递的效率,且通过const的使用,保证了引用传递的安全性。
(3)引用与指针的区别是,指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
(4)使用引用的时机。流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。