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引用的這個語義限制,意在限制這個非常規用法的潛在錯誤。