“引用(reference)”与指针象似但不是指针。引用主要有3种用法:①单独使用(一般称为“独立引用”),②作参数使用,③作返回值使用。从功能上来说,引用型变量又可以看着被引用变量的“别名”,这2个变量只是名称不同,变量的地址是同一个(共用体中的元素也是一样)。使用“引用”的好处主要是可以“逆向引用”。
常量也可以被引用,例如:“const int &ref = 10;”,这也是正确的,但这样定义无任何意义。定义独立引用时需要注意以下规则:
#include
<iostream>using namespace
std;int
main( ) {int
a ;int
&b = a; //b和a实际上是同一变量 b = 100; //b赋值为100,也就是a赋值为100 cout << a << endl; //a的地址和b的地址应该是完全一样 cout << &a << endl; cout << &b << endl; //-------▼下面代码有错,注释后才能运行▼-----------int
x[] = {12,15,20} ;int
&y = x; //错误:数组、指针不能被引用int
x1;int
&y1; //错误:引用时必须初始化 y1 = x1; //-------▲上面代码有错,注释后才能运行▲-----------return
0; }
许多教程在讲解参数引用时都喜欢选择交换两参数内容的swap(int &x, int &y)函数作例子,这的确很容易说明清楚,但并不能说这种用法优于指针作参数。
#include
<iostream>using namespace
std; //|右边为指针作参数的代码,仅作比较用。void
swap(int
&x,int
&y); //|void
swap(int
*x,int
*y); //|int
main ( ) //| { //|int
i = 12; //|int
j = 25; //| cout << "i=" << i << " j=" << j << endl; //| //| swap(i, j); //|swap(&i, &j); cout << "i=" << i << " j=" << j << endl; //| //|return
0; //| } //| //|void
swap(int
&x,int
&y) //|void
swap(int
*x,int
*y) { //|{int
t; //|int
t; //| t = x; //| t = *x; x = y; //| *x = *y; y = t; //| *y = *x; } //|}
初学者可以先跳过这一节,待学完“类”之后再来看。
#include
<iostream>using namespace
std;class
myclass { int who;public
: myclass(int
n) { who = n; cout << "构造函数调用" << who << endl; } ~myclass() { cout << "析构函数调用" << who << endl; }int
id() {return
who; } };void
f1(myclass o) { //普通变量方式传递参数 cout << "外部函数调用" << o.id() << endl; }void
f2(myclass *o) { //指针方式传递参数 cout << "外部函数调用" << o->id() << endl; }void
f3(myclass &o) { //引用方式传递参数 cout << "外部函数调用" << o.id() << endl; }int
main ( ) { myclass x1(1); f1(x1); cout << "-------" << endl; myclass x2(2); f2(&x2); cout << "-------" << endl; myclass x3(3); f3(x3); cout << "-------" << endl;return
0; }
从上面例子可以看出,用普通变量方式传递参数时,函数首先将参数复制一个副本,在函数体内使用的是副本。这个副本和参数自身不是同一个地址。而指针方式和引用方式并不产生副本,函数体内用的真是参数自身。需要注意的是,产生副本时调用了类的缺省“拷贝构造函数”,这个“拷贝构造函数”并不调用构造函数就产生了一个副本,有关详细内容参见后面章节。
这一节仍然较深,建议初学者跳过。讲解这一节内容之前,先看下面的程序,这个程序有没有毛病?
#include
<iostream>using namespace
std;int
&f();int
x;int
main ( ) { f() = 100; cout << x << endl;return
0; }int
&f() {return
x; }
许多人都认为第9句错了,少数人认为第4句可能有问题。事实上,这个程序完全正确。上面这个函数的返回值是引用类型,通过函数结果的设置反过来去改变“源头”数据,这种“逆向引用”为C++增强了很多功能,当然也有许多需要注意的地方。由于本教程面向初学者,因此到此为止,不再深入下去。