作者:李慧芹,华清远见嵌入式学院讲师。
一、简述:
引用是C++引入的新语言特性,是C++常用的一个重要内容之一,正确、灵活地使用引用,可以使程序简洁、高效。
概念:引用就是某一变量或目标的别名,对引用操作与对变量直接操作是完全一样。
定义:定义引用的表示方法与定义指针相似,只是用&代替了*:
类型标识符 &引用名=目标变量名;
例如: Clock pt1(10,10,10); Clock &pt2=pt1; 定义了pt2为pt1的引用。通过这样的定义,pt1和pt2表示同一对象。
需要强调的是:
1)&在此不是求地址运算,而是起标识作用。
2)引用并不产生对象的副本,仅仅是对象的同义词。
3)引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。不能先定义一个引用后才初始化它。
4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
那么既然引用只是某个变量或目标的别名,它有什么用途呢?下面讨论引用的两个主要用途:作为函数参数以及从函数中返回左值。
二、引用参数
1、传递可变参数
传统的c中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。
在c语言中,如果需要在函数中直接改变某个目的变量的值,则参数的传递往往是通过指针来实现的。如:在C语言中利用地址传递来实现两整数变量值交换:
void swap(int *a,int *b)
{
int t;
t=*a;
a=*b;
*b=t;
}
在C++中使用引用机制后,以上程序的c++版本为:
void swap(int &a,int &b)
{
int t;
t=a;
a=b;
b=t;
}
调用该函数的c++方法为:swap(x,y); c++自动把x,y的地址作为参数传递给swap函数,较上例C语言程序而言,又减少了2个指针形参的开销,这里就可以很清晰的看到采用引用机制的作用和优点了。
2、给函数传递大型对象
当大型对象,如结构体对象等,被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的副本,也就是参数传递时,对象无须复制。
const maxsize=100;
Class Set
{
private:
int elems[maxsize]; // 集和中的元素,maxsize 表示集合中元素个数的最大值。
int card; // 集合中元素的个数。
public:
Set () {card=0;} //构造函数
friend Set operator * (Set ,Set ) ; //重载运算符号*,用于计算集合的交集 用对象作为传值参数
// friend Set operator * (Set & ,Set & ) 重载运算符号*,用于计算集合的交集 用对象的引用作为传值参数
...
}
先考虑集合交集的实现
Set operator *( Set Set1,Set Set2)
{
Set res;
for(int i=0;i<Set1.card;++i)
for(int j=0;j>Set2.card;++j)
if(Set1.elems[i]==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems[i];
break;
}
return res;
}
由于重载运算符不能对指针单独操作,我们必须把运算数声明为 Set 类型而不是 Set * 。
每次使用*做交集运算时,整个集合都被复制,这样效率很低。我们可以用引用来避免这种情况。
Set operator *( Set &Set1,Set &Set2)
{
Set res;
for(int i=0;i<Set1.card;++i)
for(int j=0;j>Set2.card;++j)
if(Set1.elems[i]==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems[i];
break;
}
return res;
}
三、引用返回值
如果一个函数返回了引用,那么该函数的调用也可以被赋值。这里有一函数,它拥有两个引用参数并返回一个双精度数的引用:
double &max(float &d1,float &d2)
{
return d1>d2?d1:d2;
}
引用总结:
(1)引用的目的主要用于在函数参数传递中,解决大块数据或对象的传递效率和空间不如意的问题。
(2)用引用传递函数的参数,不会产生副本,提高传递的效率,参演在进行使用时通过const保证引用传递的安全性。
(3)引用与指针的区别是,指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
(4)使用引用的时机。流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。