要以引用返回函式值,則函式定義時必須遵循以下格式:
型別識別符號
&函式名
(形參列表及型別說明)
可見,以引用返回函式值,定義函式時需要在函式名前加&。引用作為函式的返回值時,函式的返回值可以理解為函式返回了乙個變數(事實上,函式返回引用時,它返回的是乙個指向返回值的隱式指標),因此,值為引用的函式可以用作賦值運算子的左運算元。另外,用引用返回乙個函式值的最大好處是,在記憶體中不產生被返回值的副本。
#include
using namespace std;
int &func()
void main()
編譯並執行上述程式,其輸出結果如圖13.1所示,可見函式func被當作賦值運算子的左運算元來使用了。
圖13.1 程式輸出結果
下面再給出乙個使用返回引用的函式作為左值的例子,它更有力地揭示了返回引用的函式的本質。
#include
using namespace std;
double array[5] = ;
double &change(int i)
int main()
編譯並執行上述程式,其輸出結果請讀者自己實驗吧。函式change的返回值為double型別的引用,而該值又是乙個由其引數i指定的陣列array中元素的引用。因此,在主函式中,當語句「change(2) = 3.14;」被執行時,change函式返回的其實是對陣列元素array[2]的引用。通過這個引用,array[2]被賦值3.14。隨後的語句「change(3) = -99.99;」同此原理。由於change返回的是陣列中特定元素的引用,所以該函式可以放在賦值語句的左邊用來對這個陣列元素進行賦值。注意前面講過沒有陣列的引用,但是指向陣列元素的引用時存在的。
在把引用作為返回值時有些一些地方需要提醒大家注意。
首先,不能返回區域性變數或臨時變數的引用,但可以返回全域性變數的引用,也就是說要注意被引用的物件不能超出作用域。主要原因是區域性變數會在函式返回後被銷毀,因此被返回的引用就成為了「無所指」的引用,這是不被允許的。例如下面這段**就是錯誤的:
int &func()
在visual c++ 6.0中,上述**在編譯時會丟擲警告「warning c4172: returning address of local variable or temporary」,儘管編譯器沒有報錯,但這仍然意味著一種不安定。而且在visual c++ 6.0中實驗上述func()函式作為左值來使用的情況,結果表明賦值並未成功,這同樣告誡我們這種用法是絕對應當被禁止的。畢竟,當函式func()返回時,區域性變數i就超出了作用域。於是由func()返回的對i的引用就是未定義的引用。而且,某些對標準c++支援更強的編譯器中會對上述func()作左值的情況報錯!另外,這類問題也可能會間接產生,這時的錯誤顯得更加隱蔽而不容易被發現,所以當返回對乙個物件的引用時,務必要仔細檢查這個物件是否會超出作用域。
其次,不能返回函式內部動態分配的記憶體的引用。雖然不存在區域性變數的被動銷毀的問題,但是在此種情況下,仍然存在一些問題。例如,被函式返回的引用只是作為乙個臨時變數出現,而沒有被賦予乙個實際的變數,那麼這個引用所指向的由new分配的空間就無法被釋放,從而造成記憶體洩漏問題。
最後,可以返回類成員的引用,但最好是const常量。這是因為當物件的屬性是與某種業務規則相關聯的時候,其賦值常常與某些其它屬性或者物件的狀態有關,於是有必要將賦值操作封裝在乙個業務規則當中。如果其它物件可以獲得該屬性的非常量引用,那麼對該屬性的單純賦值就會破壞業務規則的完整性。
將「引用」作為函式返回值型別
格式 型別識別符號 函式名 形參列表及型別說明 好處 在記憶體中不產生被返回值的副本 注意 正是因為這點原因,所以返回乙個 區域性變數的引用是不可取的。因為隨著該 區域性變數生存期的結束,相應的引用也會失效,產生runtime error 注意事項 1 不能返回 區域性變數的引用。這條可以參照eff...
「引用作為函式引數」與 「引用作為函式返回值」
一 引用作為函式引數 作為函式引數時引用有兩種原因 1 在函式內部會對此引數進行修改 2 提高函式呼叫和執行效率。關於第一點,都知道 c 裡提到函式就會提到形參和實參。如果函式的引數實質就是形參,不過這個形參的作用域只是在函式體內部,也就是說實參和形參是兩個不同的東西,要想形參代替實參,肯定有乙個值...
引用作為函式引數返回值
說明 1 以引用返回函式值,定義函式時需要在函式名前加 2 用引用返回乙個函式值的最大好處是,在記憶體中不產生被返回值的副本。例如 include float temp 定義全域性變數temp float fn1 float r 宣告函式fn1 float fn2 float r 宣告函式fn2 f...