一、引用的概念
引用就是某一變量(目標)的一個別名,對引用的操作與對變量直接操作完全一樣。引用的聲明方法:
類型標識符 &引用名 = 目標變量名;
為一個變量起一個別名。假如有一個變量a,想給它起一個別名b,可以這樣寫:
int a; //定義a是整型變量 int &b=a; //聲明b是a的引用
二、引用的一些規則
(1)引用被創建的同時必須被初始化,指針則可以在任何時候被初始化。
(2)不能有NULL引用,引用必須與合法的存儲單元關聯,指針則可以是NULL。在使用引用之前不需要測試它的合法性。相反,指針則應該總是被測試,防止其為空。
(3)一旦引用被初始化,就不能改變引用的關系,但是指定的對象其內容可以改變。指針可以被重新賦值以指向另一個不同的對象。
例1:
void main() { int a1; int &ra; // error C2530: “ra”: 必須初始化引用 }
例2:
void main() { int a1, a2; int &ra = a1; int &ra = a2; // error C2374: “ra”: 重定義;多次初始化 }
企圖使b又變成a2的引用(別名)是不行的。
例3:
int main() { int x=10; void &rx=x; // error C2182: “rx”: 非法使用“void”類型 int a[5]; int &ra[5]=a; // error C2234: “ra”: 引用數組是非法的 return 0; }
上例中的兩處錯誤說明:void修飾是不能夠聲明引用的,引用是不能夠聲明數組的,即不能夠聲明引用數組。
在任何情況下都不能使用指向空值的引用,一個引用必須總是指向某些對象。因此如果使用一個變量並讓它指向一個對象,但是該變量在某些時候也可能不指向任何對象,這時候應該把變量聲明為指針,因為這樣可以賦予空值給該變量。相反,如果變量肯定指向一個對象,這時候就可以把變量聲明為引用。不存在指向空值的引用這個事實意味着使用引用的代碼效率比指針要高。
三、常引用
常引用聲明方式:
const 類型標識符 &引用名 = 目標變量名;
用這種方式聲明的引用,不能通過引用對目標變量的值進行修改,從而使引用的目標成為const,達到了引用的安全性。
例:
int main() { int a; const int &ra=a; ra=1; // error C3892: “ra”: 不能給常量賦值 a=1; // OK return 0; }
在C++面向對象程序設計中,經常用常指針和常引用作函數參數。這樣既能保證數據安全,使數據不能被隨意修改,在調用函數時又不必建立實參的拷貝。
四、引用之間的賦值
例:
int main() { int a = 1; int b = 2; printf("a = %d\n",a); printf("b = %d\n",b); printf("a address is:%d\n",&a); printf("b address is:%d\n",&b); printf("give reference for a and b\n"); int &ra = a; int &rb = b; printf("ra = %d\n",ra); printf("rb = %d\n",rb); printf("ra address is:%d\n",&ra); printf("rb address is:%d\n",&rb); printf("let ra = rb\n"); ra = rb; printf("a = %d\n",a); printf("b = %d\n",b); printf("ra = %d\n",ra); printf("rb = %d\n",rb); printf("a address is:%d\n",&a); printf("b address is:%d\n",&b); printf("ra address is:%d\n",&ra); printf("rb address is:%d\n",&rb); return 0; }
程序執行結果為:
a = 1
b = 2
a address is: 0031f870
b address is: 0031f864
give reference for a and b
ra = 1
rb = 2
ra address is: 0031f870
rb address is: 0031f864
let ra = rb
a = 2
b = 2
ra = 2
rb = 2
a address is: 0031f870
b address is: 0031f864
ra address is: 0031f870
rb address is: 0031f864
從上例可知,雖然引用被初始化后,便不能改變引用的關系;但是,可以用給它賦值其它引用。引用之間賦值並不改變引用和被引用變量的地址,只改變了引用對象值 。

五、指針的引用
指針的引用就是某一指針的一個別名,對引用的操作與對指針直接操作完全一樣。指針引用的聲明方法:
類型標識符 *&引用名 = 目標變量名;
在某種意義上,"*"和"&"是意思相對的兩個東西,把它們放在一起有什么意義呢?。在某種程度上,指針的引用類似於二級指針(指針的指針)。
int main() { int x = 10; int *px = &x; //x的指針 int *& rpx = px; //x的指針的引用 int y = 20; int *py = &y; //y的指針 int *& rpy = py; //y的指針的引用 cout<<"x: "<<x<<endl cout<<"px:"<<px<<endl; cout<<"rpx: "<<rpx<<endl; cout<<"y: "<<y<<endl; cout<<"py:"<<py<<endl; cout<<"rpy: "<<rpy<<endl; cout<<"-------------------"<<endl; *rpx = *rpy; cout<<"x: "<<x<<endl; cout<<"px:"<<px<<endl; cout<<"rpx: "<<rpx<<endl; cout<<"y: "<<y<<endl; cout<<"py:"<<py<<endl; cout<<"rpy: "<<rpy<<endl; return 0; }
程序執行結果為:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:20
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
輸出說明*rpx = *rpy之間的賦值並未改變指針引用的值,即地址的值,而是改變了引用對象的值 。

若將上例中*rpx = *rpy;改為:
rpx = rpy;
程序執行結果為:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:10
px: 0013FF3C
rpx: 0013FF3C
y:20
py:0013FF3C
rpy:0013FF3C
輸出說明,指針引用之間的賦值只改變指針的值,引用對象的值沒有改變

指針和引用
引用類型和指針類型都可以實現通過一個變量訪問另一個變量,但訪問的語法形式不同:
引用采用的是直接訪問形式,指針采用間接訪問形式。
除了在定義時指定的被引用變量外,引用類型變量不能再引用其它變量;而指針變量定義后可以指向其它同類型的變量。因此,引用類型比指針類型要安全。
