为什么引入引用,有三个原因:
1、引用可以起到与指针相同的功能,但引用使用更方便,程序可读性更强。
2、大对象(类实例)的引用作为参数传入函数,可以提高程序的效率。
解释:
----------------------------------------------------------------------------------------------------------------------
void fun1(MyClass mc)
{
mc.a=40;
mc.method();
}
void fun2(MyClass* mc)
{
mc->a=60;
mc->method();
}
void fun3(MyClass& mc)
{
mc.a=80;
mc.method();
}
在fun1中c++将把实参的一个拷贝传递给形参。因此如果实参占内存很大,那
么在参数传递中的系统开销将很大。而在fun2和fun3中,无论是传递实参的指针
和实参的引用,都只传递实参的地址给形参,充其量也就是四个字节,系统开销
很小。
该段截自:http://www.cnblogs.com/wackelbh/archive/2009/12/29/1984064.html
-------------------------------------------------------------------
3、运算符的重载,要使用引用
解释一、
---------------------------------------------------------------------------------------------------------------------
三、返回引用的函数
引用还有一个很有用的特性:如果一个函数返回的是一个引用类型,那么该
函数可以被当作左值使用。什么是左值搞不懂先别管,只需了解:如果一个对象
或表达式可以放在赋值号的左边,那么这个对象和表达式就叫左值。
举一个虽然无用但很说明问题的例子:
例四:
1。 int i;
2。 int& f1(int&);
3。 int f2(int);
4。 f1(i)=3;
5。 f2(i)=4;
int& f1(int&i)
{
return i;
}
int f2(int i)
{
return i;
}
试试编译一下,你会发现第4句是对的,第5句是错的。对这个例子而言,i的
引用被传递给了f1,然后f1把这个引用原样返回,第4句的意义和i=3是一样的。
查了查书,引用的这个特性在重载操作符时用得比较多。但是我对重载操作
符还是稀里糊涂,所以就举不出例子了。
强调一个小问题,看看如下代码有何错误:
int &f1();
f1()=5;
...
...
int &f1()
{
int i;
int &ri=i;
return ri;
}
注意函数f1返回的引用ri是在函数体内声明的,一旦函数返回后,超出了函
数作用域,ri所指向的内存区域,即对象i所占据的内存区域就被收回了,再对这
片内存区域赋值会出错的。
本段截自:http://www.cnblogs.com/wackelbh/archive/2009/12/29/1984064.html
-------------------------------------------------------------------------
解释二、
-------------------------------------------------------------------------
2、给函数传递大型对象
当大型对象被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的副本,也就是参数传递时,对象无须复制。下面的例子定义了一个有限整数集合的类:
const maxCard=100;
Class Set
{
int elems[maxCard];
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==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems;
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==Set2.elems[j])
{
res.elems[res.card++]=Set1.elems;
break;
}
return res;
}
三、引用返回值
如果一个函数返回了引用,那么该函数的调用也可以被赋值。这里有一函数,它拥有两个引用参数并返回一个双精度数的引用:
double &max(double &d1,double &d2)
{
return d1>d2?d1:d2;
}
由于max()函数返回一个对双精度数的引用,那么我们就可以用max() 来对其中较大的双精度数加1:
max(x,y)+=1.0;
本段截自:http://blog.sina.com.cn/s/blog_60281b700100ens2.html
----------------------------------------------------------------------------------------------------------------