引用(&)是C++中的概念,初学者容易把引用和指针混淆。在一下程序中,n是m的引用,p是m的指针:
int m;
int &n = m;
int *p = &m;
n相当于m的别名,对n操作就是对m操作,n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。
*p虽然值是m,但 *p不能等同于m(比如在const的修饰下,两者不同)。
引用的一些规则如下:
1.引用被创建的同时必须被初始化(指针则可以在任何时候被初始化).
2.不能有NULL引用,引用必须与合法的储存单元关联(指针可以置为NULL).
3.引用总是指向它最初获得的那个对象,一旦引用被初始化,就不可改变引用的关系(指针则可以随时的改变所值得对象).
总的来说,在以下情况下你应该使用指针:一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针所指的对象)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[]。这个操作符典型的用法是返回一个目标对象,其能被赋值。
以下示例程序中,k被初始化为i的引用。语句k = j并不能将k修改成为j的引用,只是把k的值改变成为6。由于k是i的引用,所以i的值也变成了6。
int i = 5;
int j = 6;
int &k = i;
k = j; // k和i的值都变成了6;
上面的程序看起来象在玩文字游戏,没有体现出引用的价值。引用的主要功能是传递函数的参数和返回值。C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。
以下是“值传递”的示例程序。由于Func1函数体内的x是外部变量n的一份拷贝,改变x的值不会影响n, 所以n的值仍然是0。
void Func1(int x)
{
x = x + 10;
}
…
int n = 0;
Func1(n);
cout << “n = ” << n << endl; // n = 0
以下是“指针传递”的示例程序。由于Func2函数体内的x是指向外部变量n的指针,改变该指针的内容将导致n的值改变,所以n的值成为10。
void Func2(int *x)
{
(* x) = (* x) + 10;
}
…
int n = 0;
Func2(&n);
cout << “n = ” << n << endl; // n = 10
以下是“引用传递”的示例程序。由于Func3函数体内的x是外部变量n的引用,x和n是同一个东西,改变x等于改变n,所以n的值成为10。
void Func3(int &x)
{
x = x + 10;
}
…
int n = 0;
Func3(n);
cout << “n = ” << n << endl; // n = 10
关于引用是否占用内存的一些说明:
……
引用的实现方法有很多种。最明显的实现方式是作为一个(常量)指针,在每次使用时都作间接访问。
但在一些情况下,编译器会通过优化去掉引用。所以,不要把引用当指针使用,仅作为变量的别名使用。
……
先搞清楚什么是占内存,然后再来讨论是不是占内存,怎么占内存。
作为变量、常量、空语句、都会在编译后占用空间,从这点上看,同一变量的多次使用也是要占用内存的,因此从这个角度讲占不占内存没有任何意义。
在C 中,有关占不占内存,是以是否需要“额外”分配空间来定的,指针占一个整型空间,是因为其变量保留地址“额外”的多花了int类型空间,引用在编译以后直接以被引用的对象进行操作,其所占空间就是原对象所占空间,并没有“额外”的添加空间来保存对象、因此可以说是不占内存空间。在程序中,凡用到引用的地方,都可以用原对象替换,而程序大小、内存使用情况不变,使用指针则不可能这样。