3.1.2 引用作为函数参数
1. 引用传递参数
在作为函数参数时,引用具有指针的威力,又具有传值方式的简单性与可读性。而且使用引用可以从调用的函数返回多个值。
例如,有以下程序:
- #include <iostream.h>
- void f(int a[],int n,int &max,int &min)
- { max=min=a[0];
- for (int i=1;i<n;i++)
- { if (max<a[i]) max=a[i];
- if (min>a[i]) min=a[i];
- }
- }
- void main()
- { int a[10]={2,5,2,9,0,8,6,1,7,4};
- int max,min;
- f(a,10,max,min);
- cout << "Max:" << max << endl;
- cout << "Min:" << min << endl;
- }
上述程序中,函数f使用了两个引用,即Max和Min用于返回值。其执行结果如下:
- Max:9
- Min:0
2. 对象引用作为函数参数
在实际应用中,使用对象引用作为函数参数要比使用对象指针作为函数参数更普遍。这是因为使用对象引用作为函数参数,既具有用对象指针作为函数参数的优点,又具有用对象作为函数参数的简单性与可读性。
例如,有以下程序:
- #include <iostream.h>
- class Sample
- { int x,y;
- public:
- Sample(){ x=y=0; }
- Sample(int x1,int y1) { x=x1;y=y1;}
- void copy(Sample s) { x=s.x;y=s.y; }
- void setxy(int x1,int y1) { x=x1;y=y1; }
- void disp() { cout << "(" << x << "," << y << ")" << endl; }
- };
- void fun(Sample s1,Sample &s2)
- { s1.setxy(12,18);
- s2.setxy(23,15);
- }
- void main()
- { Sample s(5,10),t;
- s.disp();
- t.copy(s);
- t.disp();
- fun(s,t);
- s.disp();
- t.disp();
- }
上述程序中,main函数调用fun(s,t)后,由于fun函数只有第二个参数使用了对象引用,所以s对象不改变,而t对象改变了。其执行结果如下:
- (5,10)
- (5,10)
- (5,10)
- (23,15)
在函数调用过程中,实参到形参传递数据时,是将实参复制给形参,注意这种复制是浅复制,例如,有以下程序:
- #include <iostream.h>
- #include <string.h>
- class MyClass
- { char *pstr;
- int size;
- public:
- MyClass() {} //默认构造函数
- MyClass(char a[],int n) //重载构造函数
- { pstr=new char[n+1]; //分配n+1个字符空间
- strcpy(pstr,a); //复制字符串
- size=n;
- }
- ~MyClass() //析构函数
- { delete [] pstr; }
- void Copy(MyClass obj) //复制
- { this->pstr=new char[obj.size+1];
- strcpy(this->pstr,obj.pstr);
- this->size=obj.size;
- }
- void Disp() //输出pstr
- { cout << pstr << endl; }
- };
- void main()
- { MyClass s("ABC",3),s1;
- cout << "s:"; s.Disp();
- s1.Copy(s);
- cout << "s1:"; s1.Disp();
- }
上述程序中定义了一个MyClass类,其中Copy成员函数用于将形参obj对象复制给当前调用的对象,并采用深复制。可是在程序执行时却出现错误。这是因为执行s1.Copy(s)时,由于Copy成员函数的形参obj不是引用型参数,需要将实参对象s复制给形参对象obj,这种复制是浅复制,也就是说obj.pstr和s.pstr都指向同一个内存空间,当Copy函数执行完毕,调用obj的析构函数将所指空间释放了,而程序结束时,再调用s的析构函数时出现错误。
改正的方法十分简单,只需将Copy成员函数的形参obj改为引用型参数即可。因为改为引用型参数后,obj和s共享同一内存空间,当Copy函数执行完毕,不会调用obj的析构函数将所指空间释放,只有在程序结束时调用s的析构函数才释放所指空间。
在设计一个类时,如果含有指针数据成员,那么成员函数中对象形参通常采用引用类型,否则会出现错误。