C 非常量引用不能指向臨時物件

2022-03-08 17:52:55 字數 1745 閱讀 7154

目錄

舉例分析

解決1、舉例

非常量引用 指向 臨時物件 —— 即:將 臨時物件 傳遞給 非常量引用型別。

如以下情況就會出現:

實現實數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 返回的臨時物件不買單,直接報了個「沒有匹配的函式」 的錯誤。

2、分析

以c++的語義來說,如果乙個程式設計師只想傳遞引數給函式,而不希望函式修改傳入的引數時,那麼,或者使用值傳遞,或者採用常量型引用。考慮到大物件複製時產生的開銷,一般使用常量型引用const &。如果函式的引數是某個型別的乙個非常量的引用,那就相當於告訴編譯器,程式設計師希望得到函式對引數的修改結果。

臨時變數是由編譯器生成的,c++語言規範沒規定編譯器生成臨時變數的規則,程式設計師無法得知由編譯器生成的臨時變數的名字,程式設計師無法訪問那個臨時變數。這意味著,以引用的方式傳遞乙個臨時變數做為函式引數,如果函式內部對此臨時變數做了修改,那麼函式返回後,程式設計師無法獲得函式對臨時變數的修改。函式對臨時變數所做出的所有更改,都將丟失。

一方面,在函式申明中,使用非常量型的引用告訴編譯器你需要得到函式對某個物件的修改結果,可是你自己又不給變數起名字,直接丟棄了函式的修改結果,編譯器只能說:「大哥,你這是幹啥呢,告訴我把結果給你,等我把結果給你了,你又直接給扔了,你這不是在玩我嗎?」

同時,c++的標準 為了防止給常量或臨時變數(只有瞬間的生命週期)賦值(易產生bug),只許使用const引用之。

3、解決

friend ostream &operator

<< (ostream& outs,rational &rational); //

非常量引用

改為值傳遞:

ostream &operator

<<(ostream &outs, rational ratiaonl) //值傳遞

改為常量引用:

ostream &operator

<<(ostream &outs,const rational &rational) //常量引用

引用不能 rebinding

引用 reference 就是某一變數的乙個別名。對引用的操作與對變數直接操作完全一樣。引用 陷阱 引用宣告完畢後,相當於目標變數名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作為其他變數名的別名。簡單說就是 引用可以 modify 被繫結的變數 但不能 rebinding 其他變數 in...

C 中引用不能重新賦值的理解

教材上說引用是不能重新賦值的,可是下面的程式能正常執行,不會出錯。這裡怎麼出現了引用賦值語句呢 語句 1 是不是教材錯了?原因究竟是什麼呢?請看如下程式 include void main int i 1,j 5 int k i k j 語句 1 cout i j k 首先想想程式執行結果應該是什麼...

c 的引用 常量引用

c 中的引用不用考慮太多解引用的東西 include using namespace std void func int ref intmain 在c 中,int ref a等價於int const ref a,也就是說ref直接存的是a的位址。但是實際上想要對ref的值進行修改的話,是不需要解引用...