C++ const引用、臨時變數 引用引數
C++引用—臨時變數、引用引數和const引用
如果實參與引用引數不匹配,C++將生成臨時變數。如果引用引數是const,則編譯器在下面兩種情況下生成臨時變數:
實參型別是正確的,但不是左值
實參型別不正確,但可以轉換為正確的型別
左值引數是可被引用的資料物件,例如,變數、陣列元素、結構成員、引用和被解除引用的指標都是左值,非左值包括字面常量和包含多項式的表示式。定義一個函式
Double refcube(const double& ra) { Returnra*ra*ra; } double side = 3.0; double* pd = &side; double& rd = side; long edge = 5L; double lens[4]={2.3,3.4,4.5,6.7}; double c1 = refcube(side); // ra 是side double c2 = refcube(lens[2]); // ra是lens[2] double c3 = refcube(rd); // ra 是 rd double c4 = refcube(*pd); // ra 是*pd double c5 = refcube(edge); // ra 是臨時變數 double c6 = refcube(7.0); // ra 是臨時變數 double c7 = refcube(side+10.0); // ra 是臨時變數
引數side lens[2] rd 和*pd都是有名稱的、double型別的資料物件,因此可以為其建立引用,而不需要臨時變數。但是edge雖然是變數,型別卻不正確,double引用不能指向long。另一方面,引數7.0和side+10.0的型別都正確,但沒有名稱,在這些情況下,編譯器都將生成一個臨時匿名變數,並讓ra指向它。這些臨時變數只在函式呼叫期間存在,伺候編譯器便可以任意將其刪除
那麼為什麼對於常量引用,這種行為是可行的,其他情況下卻不行呢?
Void swapr(int& a,int& b)
{
Inttemp;
Temp=a;
A= b;
B= temp;
}
在早期的C++較寬鬆的規則下,執行下面的操作將發生什麼?
Long a = 3,b = 5;
Swapr(a,b);
這裡的型別不匹配,因此編譯器將建立兩個臨時的int變數,將他們初始化為3和5,然後交換臨時變數的內容,而a和b保持不變
簡而言之,如果接受引用引數的函式的意圖是修改作為引數傳遞的變數,則建立臨時變數將阻止這種意圖的實現,解決方法是,禁止建立臨時變數,下載的C++標準正是正陽做的、
現在來看refcube()函式,該函式的目的只是使用傳遞的值,而不是修改他們,因此臨時變數不會造成任何不利的影響。反而會使函式在可處理的引數種類方面更通用。因此,如果宣告將引用指定為const,C++將在必要時生成臨時變數、實際上,對於形參為const引用的C++函式,如果實參不匹配,則其行為類似於按值傳遞,為確保原始資料不被修改,將使用臨時變數來儲存值、
(PS:如果函式呼叫的引數不是左值或與相應的const引用引數的型別不匹配,則C++將建立型別正確的匿名變數,將函式呼叫的引數的值傳遞給該匿名變數,並讓引數來引用該變數)
應儘可能使用const
使用cosnt可以避免無意總修改資料的程式設計錯誤
使用const使函式能夠處理const和非const實參,否則將只能接受非const資料
使用const引用使函式能夠正確生成並使用臨時變數