引用(reference)是c++对c语言的重要扩充。
1. 引用的概念
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。
(1). 引用就是为某个变量或隐含的临时变量起个别名,对别名的操作等同于对目标变量的操作;
(2). 引用本身不是变量,它是某个变量的别名,其本身不占存储空间。
2. 引用的初始化:
(1). 定义引用时必须指出目标对象(即声明的同时进行初始化) ;
例如,
int i =5;
int &ri = i;
(2). 引用数据成员的初始化:
a. 必须在构造函数的初始化列表中进行;
b. 还必须在复制构造函数的初始化列表中进行;
c. 一旦初始化了一个引用,就不能修改它所引用的对象了(即这个引用不能被赋值),因此,不必在赋值函数中尝试对引用赋值;
(3). 引用不同于变量,下面的类型声明都是非法的:
a. int &a[5]; //不能建立引用数组
b. int &*p; //不能建立指向引用的指针
c. int &&ri; //不能建立引用的引用
3.引用的实质:
(1). 下面两种情况系统会建立临时变量:
a.对常量的引用,这时,对引用的操作只是对临时变量的操作(即对引用的改写,只改写临时变量,而不能改写常量),例如:
const int i = 5;
int &ri = i; //建立常量的引用
printf(" i = %d , ri = %d/n", i, ri); //output: i = 5 , ri = 5
ril += 20; //修改引用
printf(" i = %d , ri = %d/n", i, ri); //output: i = 5 , ri = 30
b.当初始化用的变量与所声明的引用的类型不一致时,例如:
int i =5;
float &rf = i;
printf(" i = %d , rf = %d/n", i, rf); //output: i = 5 , rf = 5
rf +=20;
printf(" i = %d , rf = %d/n", i, rf); //output: i = 5 , rf = 25
(2). 实质:
引用实际上是通过一(常量)指针来实现的,每次引用它都在进行间接引用。如声明
double &dr = 1;
可以解释为:
double *drp; //把引用表示为一指针
double temp; //引入一临时变量
temp = double(1); //类型转换
drp = &temp; //指向临时变量
4. 引用的用法:
(1). 引用作为函数参数:
.必须在构造函数的初始化列表中进行;
.函数不能返回自动变量的引用,因为其实体将在函数返回时被撤销;
.从效率来说,和指针的效率一样;从语法和理解上来看,又和变量的使用差不多。
(2). 返回引用的函数:
.函数返回值时,要生成一个值的副本,而用引用返回值时,不生成值的副本。所以,绝对不能返回不在作用域内的对象的引用;
5. 例子程序:
/* IDE环境: Dev-C++ 4.9.9.2 */
#include <stdio.h>
class M
{
public:
M() { x=y=0; }
M(int i, int j) { x=i; y=j; }
void copy(M &m); //引用作为函数参数
void setxy(int i, int j) { x=i; y=j; }
void print()
{
printf("x = %d; y = %d /n", x,y);
}
private:
int x, y;
};
void M::copy(M &m)
{
x=m.x;
x=m.y;
}
void fun(M m1, M &m2);
int main()
{
M p(1, 2), q;
q.copy(p);
fun(p, q);
p.print();
q.print();
while(1);
return 0;
}
void fun(M m1, M &m2)
{
m1.setxy(3, 4);
m2.setxy(5, 6);
}
/*运行结果为:
x = 1, y = 2
x = 5, y = 6
*/
代码说明:
类M的成员函数copy(M &m)中,m是引用类型,作为函数参数。