關於const引用

2021-09-30 14:11:05 字數 2748 閱讀 9993

簡單地說,const引用是指–指向const的引用(其實這樣說不恰當,在我的理解中,const引用中的const只是限定了不能通過此引用去修改變數的值),和const指標一樣,const引用可以與常量繫結,也可以與變數繫結,只是不能通過這個const引用來改變繫結物件的值,就如之後要講的const指標類似。

另外,引用的物件是常量還是非常量可以決定其能參與的操作,卻無論如何都不會影響到引用和物件的繫結關係。

1、初始化的必要性: 一旦引用已經定義,它就不能再指向其他的物件.這就是為什麼它要被初始化的原因。

2、const引用可以用不同型別的物件初始化(只要能從一種型別轉換到另一種型別即可),也可以是不可定址的值,如文字常量。例如:

int i=42;

const

int &r1=i;

1.const

int &rb = 1;//允許將引用繫結到字面值上

2.const

int &rc = r1 * 2;//允許將引用繫結到常量表示式上 不可定址

3.double d = 3.14;

const

int &rd = d;//這是允許的 但是如果是非const引用就不行

上面的三個例子執行時,由於初始值為不可定址的值,或者型別不匹配的物件或者是字面值常量,編譯器會生成臨時物件,並將常量引用繫結到該臨時物件上;如:3中,編譯器會先將double的d經過型別轉換放到乙個整形的臨時物件中,然後將常量引用繫結到這個臨時物件,如下:

const

int tmp = d; //生成臨時變數

const

int &rd = tmp; //繫結臨時變數

因此,對於普通的引用,繫結物件必須嚴格的匹配: 因為如果型別不匹配,那麼定義的引用會被繫結到乙個臨時物件上去,而在對引用做相應的操作的時候,實際上操作的是臨時物件,並非初始化時想要繫結的物件!而對於常量引用,因為其並不能修改繫結的物件,所以將其繫結到臨時物件也是可以的。

3、不允許非const引用指向需要臨時物件的物件或值,對於普通的引用,繫結物件必須嚴格的匹配,即,編譯器產生臨時變數的時候引用必須為const!!!

int a = 2;

int &ref1 = a;// ok.有過渡變數。

const

int &ref2 = 2;// ok.編譯器產生臨時變數,需要const引用

int iv = 100;

int *&pir = &iv;//錯誤,非const引用對需要臨時物件的引用(非常量初始值必須為左值)

//因為pir為非常量引用,而iv的位址值不是物件,編譯器會產生臨時物件儲存iv的位址值

const

int* &pir = &iv;//錯誤 因為pir也不是常量引用,等價於 int const *&pir = &iv; pir為繫結到乙個指向int常量的指標的普通引用;

int *const &pir = &iv;//ok 注意與上面的差別 頂層const和底層const

int *pa = &iv;

const

int *&pir = pa; //正確 pa是左值

const

int ival = 1024;

int *&pi_ref = &ival; //錯誤,非const引用是非法的

//修改

const

int ival = 1024;

const

int *const &pi_ref = &ival; //兩個const代表的含義

const引用繫結到型別不匹配的物件型別上時發生了什麼:

double d=3.1415;  

const

int &rd=d;

執行const int &rd=d時,發生了這種情況:const int temp=d;const int &rd=temp;所謂臨時變數就是編譯器需要乙個空間暫存表示式的求值結果時臨時建立的未命名的物件。而假如rd不是乙個常量引用,在對rd賦值時,就會改變rd所繫結物件的值。但此時繫結的物件是乙個臨時的量,它沒有名字,而不是繫結了d,既然rd繫結了d,肯定是想通過rd改變d的值,否則幹嘛將d繫結到rd呢?但是此時非const修飾的rd改變不了d的值,那繫結也就無意義,所以編譯器不允許這樣做。

4、const引用僅對引用可進行的操作作了限定,而對引用的物件本身是不是const沒有做限定,所以我們仍然可以改變其指向物件的值,只是不能通過引用:

#include 

using

namespace

std;

int main()

如果我們通過ir來改變val的值,編譯時會出錯。但是我們仍然可以通過val直接改變其值。

最後自己的理解就是,const引用只是表明,保證不會通過此引用間接的改變被引用的物件!const引用表示,試圖通過此引用去(間接)改變其引用的物件的值時,編譯器會報錯!這並不意味著,此引用所引用的物件也因此變成const型別了。我們仍然可以改變其指向物件的值,只是不能通過引用。

常量引用只有2種情況會繫結到實際的物件:一是常量引用的初始值為const物件,且該物件型別與常量引用型別相同(如const int i ; const int &r = i;);二是常量引用的初始值為非const物件,且該物件也與常量引用型別(除去const的型別)相同(如int i; const int &r = i;)。這種情況下,繫結的非const物件內容可以用其他普通引用改變。  

引用 const引用和非const引用

引用構造了物件的乙個同義詞,是c 物件的另乙個名字。在實際程式中,引用的主要作用是作函式的形參。引用是一種復合型別1,它通過在變數名前新增 來定義。在使用引用的情況下,每一種引用型別都關聯到某一其他型別。c 不能定義引用型別的引用,但是可以定義任何其他型別的引用。int a 100 int refa...

const引用與非const引用

const引用可讀不可改,與繫結物件是否為const無關,注意區分const引用與對const物件的引用 非const引用可讀可改,只可與非const物件繫結 const int ival 1024 const int refval ival ok both reference and object...

C 關於const引用的測試

由書中內容 p55 p56 可知,const引用有如下幾種常見例子 第一種 int i 10 const int r1 i 輸出r1 10 i 20 cout此時const引用r1是變數i的引用,對r1不可進行修改賦值等操作,但是我們可以修改變數i已達到間接修改r1的目的,其原因是r1是乙個cons...