目錄 |
非常量引用 指向 臨時對象 —— 即:將 臨時對象 傳遞給 非常量引用類型。
如以下情況就會出現:
實現實數Rational類,實數可以使用+號相加,運算的結果要可以使用 "cout << " 以分數形式輸出 實數Rational 的值:
Rational a(4,5); Rational b(1,3); cout << a+b << endl;
在這里需要重載2個操作符函數:“+”號 和 “<<” 輸出符號
//在Rational類中定義如下 friend ostream &operator<< (ostream& outs,Rational &rational); Rational operator+(Rational &secondRational);
在這種定義下,就會出現我們所要說的問題:非常量引用不能指向臨時對象。
a+b 函數返回一個Rational類的臨時對象;而 << 操作函數的參數卻是 Rational & rational 。這種情況函數會報錯如下:
no match for 'operator<<' in 'std::cout << a.Rational::operator+(((Rational&)(& b)))'
雖然定義了 operator<< 。但是編譯器對 a+b 返回的臨時對象不買單,直接報了個“沒有匹配的函數” 的錯誤。
以C++的語義來說,如果一個程序員只想傳遞參數給函數,而不希望函數修改傳入的參數時,那么,或者使用值傳遞,或者采用常量型引用。考慮到大對象復制時產生的開銷,一般使用常量型引用const &。如果函數的參數是某個類型的一個非常量的引用,那就相當於告訴編譯器,程序員希望得到函數對參數的修改結果。
臨時變量是由編譯器生成的,C++語言規范沒規定編譯器生成臨時變量的規則,程序員無法得知由編譯器生成的臨時變量的名字,程序員無法訪問那個臨時變量。這意味着,以引用的方式傳遞一個臨時變量做為函數參數,如果函數內部對此臨時變量做了修改,那么函數返回后,程序員無法獲得函數對臨時變量的修改。函數對臨時變量所做出的所有更改,都將丟失。
一方面,在函數申明中,使用非常量型的引用告訴編譯器你需要得到函數對某個對象的修改結果,可是你自己又不給變量起名字,直接丟棄了函數的修改結果,編譯器只能說:“大哥,你這是干啥呢,告訴我把結果給你,等我把結果給你了,你又直接給扔了,你這不是在玩我嗎?”
同時,C++的標准 為了防止給常量或臨時變量(只有瞬間的生命周期)賦值(易產生bug),只許使用const引用之。
friend ostream &operator<< (ostream& outs,Rational &rational); //非常量引用
改為值傳遞:
ostream &operator<<(ostream &outs, Rational ratiaonl) //值傳遞
改為常量引用:
ostream &operator<<(ostream &outs,const Rational &rational) //常量引用