標籤:ref 拷貝 int c++ 變數
通俗來講,引用(reference)就是給對象另外一個名字。
1)引用必須被初始化
int &ref; // 錯誤
int val=10;int &ref2=val; // ref2指向val(val的另一個名字)
在初始設定變數時,初始值會被拷貝到建立的對象中。在定義引用時,程式把引用和它的初始值綁定(bind)在一起,而不是將初始值拷貝到引用。一旦初始化完成,引用將和它的初始值對象一直綁定在一起。因為無法令引用重新綁定到另一個對象,因此引用必須初始化。
補充:所謂對象,就是一Block Storage資料並具有某種類型的記憶體空間。
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綁定對象iconst int &r2= i; // r2也綁定對象i,但是不能通過r2修改i的值r1= 0; // r1並非常量,i的值修改為0r2= 0; // 錯誤: r2是一個常量引用
r2綁定非常量整數i是合法的,但是不能通過r2修改i的值。但是可以通過直接賦值或者通過非常量引用來修改。
【C++注意事項】3 引用