在C++中提出了引用这个概念,它和指针类似,但用起来更方便。
一、普通引用
这里的引用有时候也称为别名,实际就是说两个不同名称的标识符指向了同一个内存地址。
#include < iostream > using namespace std; int main(){ int y; int & r = y; const int & q = 12 ; cout << y << " " << r << endl; r ++ ; cout << y << " " << r << endl;}这里有一个比较特别的地方,就是可以取常量的引用,但引用也必须设为常量,这里编译器为12分配了存储单元,值被初始化为12,q就是这个存储单元的别名。 后面可以看到,r 增加后,y也增加了,说明它们指向的是同一块地址。
使用引用时需要注意以下规则:
1) 当引用被创建时,它必须被初始化。 2)一旦一个引用被初始化指向一个对象,它就不能改变为另一个对象的引用。 3)不可能有NULL的引用。必须确保引用是和一块合法的存储单元关联。
二、函数中的引用
1.引用参数
引用常被用来做函数的参数,这个时候它的行为就和指针一样了,但语法更清晰。就是常说的按引用传递。
void f( int * x){ ( * x) ++ ; } void g( int & x){ x ++ ;} int main(){ int a = 0 ; f( & a); g(a);}不过有时候这种传递参数的方法比较隐蔽,不知道传的参数是否会被修改。
另外,如果要传递常量的话,就必须声明函数参数为常量引用: void f(const int& a) {}; f(1);
2.指针引用 有时候我们需要传递的是指针的地址,在C语言里我们通常是这样: void f(int**); int i=4; int* ip=&i; f(&ip); 引用则可以有更简单的语法
#include < iostream > using namespace std; void increment( int *& i) { i ++ } int main(){ int * i = 0 ; cout << " i= " << i << endl; increment(i); cout << " i= " << i << endl;}3. 返回引用 有些用户自定义的类型很大,如果按值返回开销很大,这时采用按引用返回,就只返回地址,这样比较快 捷。这个是在运算符重载中经常遇见的。但需要注意的是“不要返回临时量,也就是局部变量”
class Widget{ public : int x;};Widget & f(Widget & a){ a.x = 10 ; return a; // OK! }Widget & g(){ Widget a; return a; // 返回临时量 ,error }Widget & h(){ static Widget a; return a; // 静态 OK! } int main(){ Widget a; Widget b = f(a); Widget c = h();}在C++里面引用的运用是很灵活的,它最重要的地方就是在拷贝构造函数里面。这个主题就下次再讲了。