【C++注意事項】3 引用

nomasp發表於2015-05-20

通俗來講,引用(reference)就是給物件另外一個名字。

1)引用必須被初始化

int &ref;  // 錯誤
int val=10;
int &ref2=val;  // ref2指向val(val的另一個名字)

在初始化變數時,初始值會被拷貝到新建的物件中。在定義引用時,程式把引用和它的初始值繫結(bind)在一起,而不是將初始值拷貝到引用。一旦初始化完成,引用將和它的初始值物件一直繫結在一起。因為無法令引用重新繫結到另一個物件,因此引用必須初始化。

補充:所謂物件,就是一塊儲存資料並具有某種型別的記憶體空間。

2)引用即別名。引用並非物件,它只是另外一個已經存在的物件的名字。

3)引用型別的初始值必須是一個物件。

int &ref3=10;  // 錯誤

4)可以把引用繫結到const物件上,就像繫結到其他物件一樣,它被稱為對常量的引用(reference to const)。與普通引用不同的是,對常量的引用不能被用作修改它所繫結的物件。

const int cVal= 10;
const int &cRef= cVal;  // 正確: 引用及其對應的物件都是常量
cRef=20;  // 錯誤: cRef是對常量的引用
int &ref2= cVal;  // 錯誤: 不能讓一個非常量引用指向一個常量物件

5)除了下面的兩種例外情況外,所有的引用型別都要和與之繫結的物件嚴格匹配。

double dVal=20.0;
int %ref4 = dVal;  // 錯誤

第一種例外情況就是在初始化常量引用時允許用任意表示式作為初始值,只要該表示式的結果能轉換成引用的型別即可。

【C++注意事項】1 資料型別及型別轉換

尤其,允許為一個常量引用繫結非常量的物件、字面值,甚至是個一般表示式。

int i=42;
const int &r1=i;  // 允許const int&繫結到一個普通int物件上
const int &r2=42;  // 正確: r2是一個常量引用
const int &r3=r1*2;  // 正確: r3是一個常量引用
int &r4 =r1*2;  // 錯誤: r4是一個普通的非常量引用

下面通過一個示例來說明當一個常量引用被繫結到另一種型別上時到底發生了什麼。

double dval= 3.14;
const int &ri= dval;

此處的ri引用了一個int型的數。對ri的操作應該是整數運算,但dval卻是一個雙精度浮點數而非整數。因此為了確保讓ri繫結一個整數,編譯器把上述程式碼變成了如下形式:

cosnt int temp= dval;
const int *ri= temp;

在這種情況下,ri其實是繫結了一個臨時量(temporary)物件。所謂臨時量物件就是當編譯器需要一個空間來暫存表示式的求值結果時臨時建立一個未命名的物件。臨時量物件常被簡稱為臨時量。

如果ri不是常量就會允許對ri賦值,這樣就會改變ri所引用物件的值。而此時繫結的物件是一個臨時量而非dval。既然用ri引用了dval,那麼就是想通過ri修改dval的值了,否則幹嘛要給ri賦值呢?那麼既然不會想著把引用繫結到臨時量上,C++語言便將這種行為歸為非法。

6)對const的引用可能引用一個並非const的物件。常量引用僅對可參與的操作做出了限定,對於引用的物件本身是不是一個常量未作限定。因此物件也可能是一個非常量,所以允許通過其他途徑改變它的值。

int i= 42;
int &r1= i;  // 引用ri繫結物件i
const int &r2= i;  // r2也繫結物件i,但是不能通過r2修改i的值
r1= 0;  // r1並非常量,i的值修改為0
r2= 0;  // 錯誤: r2是一個常量引用

r2繫結非常量整數i是合法的,但是不能通過r2修改i的值。但是可以通過直接賦值或者通過非常量引用來修改。



感謝您的訪問,希望對您有所幫助。 歡迎大家關注、收藏以及評論。

我的更多部落格文章:NoMasp部落格導讀


為使本文得到斧正和提問,轉載請註明出處:
http://blog.csdn.net/nomasp


相關文章