通过对象名称直接访问对象,优点是直观,操作哪个对象一目了然, 缺点一个函数内部不能使用另一个函数的局部变量;
通过指针(或地址)间接访问对象,优点是无所不能,缺点是程序 中大量出现的间接访问,实在分不清具体是哪个对象,需要通过上 下文去分析。
C++扩充了C语言对象访问方式,提供了引用访问。通过引用访问对象,结合了按名访问和按地址访问各自的优点,非常适合作为函数参数。
1. 引用的声明
简单地说,引用(reference)就是一个对象的别名(alias name), 其声明形式为:
引用类型 &引用名称=对象名称 , ......;
int x; //定义整型变量x
int &r=x; //声明r是x的引用
引用的规则:
(1)声明一个引用类型变量时,必须同时初始化它,声明它是哪 个对象的别名,即绑定对象。例如:
int &r; //错误,引用是const类型,必须在声明时初始化
int x, &r=x; //正确 声明r是x的引用
(2)不能有空引用,引用必须与有效对象的内存单元关联。
(3)引用全部是const类型,声明之后不可更改(即不能再是别的对象的引用)。例如:
int x, y; //定义整型变量x,y
int &r=x; //正确 声明r是x的引用
int &r=y; //错误 r不能再是别的对象的引用
(4)指定类型的引用不能初始化到其他类型的对象上,例如:
double f; //定义浮点型变量f
int &r=f; //错误 r值整型的引用,不能绑定到浮点型的对象上
(5)引用初始化与对引用赋值含义完全不同,例如:
int x; //定义整型变量x
int &r=x; //初始化 指明r是x的引用,即将r绑定到x
r=100; //引用赋值 100赋值到r绑定的内存单元中(即x)
(6)取一个引用的地址和取一个对象的地址完全一样,都是用取地址运算。例如:
int x, &r=x; //定义整型变量x,y
int *p1=&x; //p1指向x
int *p2=&r; //p2指向r,本质上指向x
2.引用作为函数的形参
C++之所以扩充引用类型,主要是把它作为函数形参,使得C++中给一个函数传递参数有三种方法:
①传递对象本身;(值传递)
②传递指向对象的指针;(地址传递)
③传递对象的引用。(引用传递)
变量、指针、引用作为函数参数比较:
//程序1 传递对象本身
2 #include <iostream>
3 using namespace std;
4 //对象作为函数形参
5 void swap(int a,int b)
6 { int t;
7 t=a, a=b, b=t;
8 }
9 int main()
10 { int x=10, y=20;
11 swap(x,y);
12 cout<<x<<","<<y;
13 return 0;
14 }
//程序2 传递对象的指针
#include <iostream>
using namespace std;
//指针作为函数形参
void swap(int *a,int *b)
{ int t;
t=*a, *a=*b, *b=t;
}
int main()
{ int x=10, y=20;
swap(&x,&y);
cout<<x<<","<<y;
return 0;
}
//程序3 传递对象的引用
#include <iostream>
using namespace std;
//引用作为函数形参
void swap(int &a,int &b)
{ int t;
t=a, a=b, b=t;
}
int main()
{ int x=10, y=20;
swap(x,y);
cout<<x<<","<<y;
return 0;
}
显然,函数引用传递方式也可以实现多个数据结果返回到主调函数中,其功能与指针方式相同。但指针方式返回数据结果必须:
①实参为地址,即进行“&”取地址运算;
②形参分配指针变量接受实参地址;
③函数内部使用指针间接访问,即进行“*”间接访问运算。而引用传递方式把这个过程简化了。
使用引用作为函数形参,比使用指针变量简单、直观、方便,特别是避免了在被调函数中出现大量指针间接访问时,所指对象究竟是哪个具体对象伤脑筋的问题,从而降低了编程的难度。
3.引用作为函数返回值
函数的返回值可以是引用类型,即函数返回引用,其定义形式为:
引用类型& 函数名(形式参数列表)
{
函数体
}
函数返回值、指针、引用的对比:
//程序1 函数返回值
#include <iostream>
using namespace std;
int max(int a,int b)
{ return (a>b?a:b); }
int main()
{ int x=10,y=20,z;
z = max(x,y);
cout << z;
return 0;
}
//程序2 函数返回指针
#include <iostream>
using namespace std;
int* max(int a,int b)
{ return (a>b? &a:&b); }
int main()
{ int x=10,y=20,*z;
z = max(x,y);
cout << *z;
return 0;
}
//程序3 函数返回引用
#include <iostream>
using namespace std;
int& max(int &a,int &b)
{
return (a>b? a:b);
}
int main()
{
int x=10,y=20,z;
z = max(x,y);
cout << z;
return 0;
}
可以看出,函数返回引用与函数返回值有重大区别,它不是返回一个临时对象,而是相当于返回实体对象本身。正因为如此,函数返回引用可以作为左值。例如:
int& fun(int &a,int &b)
{ return (a>b? a:b); }
int x=10,y=20,z=5;
fun(x,y)=z; //调用fun函数后相当于y=z;
cout << y;