2010-01-18 70 views
10

以下代碼如何在C++中工作?它合乎邏輯嗎?常量引用的文字初始化

const int &ref = 9; 
const int &another_ref = ref + 6; 

爲什麼C++允許const引用的文字初始化,當非const引用不允許時呢?例如爲:

const int days_of_week = 7; 
int &dof = days_of_week; //error: non const reference to a const object 

這可以通過,一個非const引用可被用來改變它指的是變量的值的事實來解釋。因此,C++不允許對const變量進行非const引用。

這可能是一個可能的解釋? C++不允許:

int &ref = 7; 

因爲那是不符合邏輯,但:

const int &ref = 7; 

幾乎等同於:

const int val = 7; 

所以文字初始化允許const的變量。

P.S .:我目前正在學習Lippman的C++入門書。

回答

7

所以你可以這樣寫代碼:

void f(const string & s) { 
} 

f("foobar"); 

雖然嚴格來說什麼是真正發生的事情在這裏並不被綁定到一個常量引用文字 - 而不是temprary字符串對象被創建:

string("foobar"); 

和這個無名字符串綁定到引用。

請注意,創建非參數引用變量實際上非常不尋常 - 引用的主要目的是作爲函數參數和返回值。

6

經常提到可以用文字和臨時被初始化,因爲你可以平凡它們轉化爲明確的變量:

int const& ans = 42; 
// tranformed: 
int __internal_unique_name = 42; 
int const& ans = __internal_unique_name; 

或者當壽命不延長,如函數參數:

f("foobar"); 
// transformed: 
{ 
    string __internal_unique_name = "foobar"; 
    f(__internal_unique_name); 
} 

(注意在這種情況下的顯式塊)

儘管在非常量情況下可能做類似的事情,但這只是不允許使用C++。但是,C++ 0x(下一個標準)將具有r值引用。


如果它是不明確的,ref + 6從您的代碼創建一個臨時對象,你可以想像爲:

int const& ref = int(9); 
int const& another_ref = int(ref + 6); 

// transformed: 
int __A = 9; 
int const& ref = __A; 
int __B = ref + 6; 
int const& another_ref = __B; 

這可能會幫助你理解/可視化所發生的事情,但你應該不要寫這樣的真實代碼。此外,我使用雙下劃線名稱來說明這些名稱是實現細節(由編譯器使用),不應該由您使用。任何包含相鄰下劃線的名字都保留給C++實現。

+0

+1。但我認爲你的第二個例子將被轉換爲{__internal_unique_name(「foobar」); f(__ internal_unique_name); } – mmmmmmmm 2010-01-18 18:48:55

+0

@rstevens:無關緊要:轉換不能是明確的,在這種情況下它們是相同的。 – 2010-01-18 19:00:33