1. 程式人生 > >const引用與非const引用

const引用與非const引用

const引用只讀不可修改,與繫結物件是否為const無關。

非const引用可讀可改,只可與非const物件物件繫結

const intival = 1024;

//int &ref2 = ival; //error:nonconst reference to a const object

const int&refval = ival; //ok:both reference and objectare const

非const引用只能繫結到與該引用同類型的物件,const引用則可以繫結到不同但相關的型別的物件或繫結到左值,

const引用可以初始化為不同型別的物件或者初始化為右值,如字面值常量

int i = 42;

//legal for constreference only

const int&r = 42;

const int&r2 = r + i;

double dval = 3.14;

const int&ri = dval;

上面,同樣的初始化對於非const引用是不合法的,將導致編譯誤。

引用在內部存放的是一個物件的地址,它是該物件的別名。對於不可定址的值,如文字常量,以及不同型別的物件,編譯器為了實現引用,必須生成一個臨時物件,引用實際上指向該物件,但使用者不能訪問它。

例如:

double dval = 23;

const int &ri = dval;

編譯器將其轉換為:

int tmp = dval; //double -> int

const int &ri = tmp;

const int t = 9;

const int &k = t;

cout << &t << endl;

cout << &k << endl;

{

   intt = 9;

   int&k = t;

   cout << &t <<endl;

   cout << &k <<endl;

}

如果是對一個常量進行引用,則編譯器 首先建立一個臨時變數,然後將該常量的值置入臨時變數中,對該引用的操作就是對該臨時變數的操作。

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

int main()

{

       int ival= 1024;

       const int &ir = ival;

       ival++;

       //ir++;

       cout << ival << " " << ir << endl;

    system("pause");

       return 0;

}

int main()

{

    printf("begin\n");

       constTest &obj = 2;

       /*

       Test tmp = 2; //建構函式

       const Test &obj = tmp; //構造解構函式

       */

       obj.print(); //列印

       printf("end\n");

       system("pause");

       return 0;

}

如果一個引數是以非const引用傳入,c++編譯器就有理由認為程式設計師會在函式中修改這個值,並且這個被修改的引用在函式返回後要發揮作用。但如 果你把一個臨時變數當作非const引用引數傳進來,由於臨時變數的特殊性,程式設計師並不能操作臨時變數,而且臨時變數隨時可能被釋放掉,所以,一般說來, 修改一個臨時變數是毫無意義的,據此,c++編譯器加入了臨時變數不能作為非const引用的這個語義限制,意在限制這個非常規用法的潛在錯誤。