一、引用的意義
- 引用作爲變量別名而存在,因此在一些場合可以代替指針;
- 引用相對於指針來說具有更好的可讀性和實用性;
- 函數中的引用形參不需要 進行初始化。
- 如下圖1所示,可以看用引用作爲形參的函數在使用時會方便很多,因爲不用像指針那樣需要取變量地址。
圖 1
二、特殊的應用
(1)const引用
在C++中可以聲明const引用,語法形式:const Type& name = var;
const引用讓變量擁有隻讀屬性,不可通過引用改變變量值,但還是可以通過指針修改變量值。如下圖2所示;
圖2
(2)當使用常量對const引用進行初始化時,C++編譯器會爲常量值分配空間,並將引用名作爲這段空間的別名;使用常量對const引用初始化後將生成一個只讀變量。如下圖3所示:
圖3
三、引用的本質
- 引用在C++中的內部實現是一個指針常量;如圖4所示;
- C++編譯器在編譯過程中用指針常量作爲引用的內部實現,因此引用所佔用的空間大小與指針相同。
- 從使用的角度,引用只是一個別名,C++爲了實用性而隱藏了引用的存儲空間這一細節。如圖5的代碼執行後的結果如圖6所示;從執行的結果可看出引用所佔用的空間大小與指針相同。
圖5
圖6
四、引用的意義
C++中的引用旨在大多數的情況下代替指針
功能性:可以滿足多數需要使用指針的場合
安全性:可以避開由於指針操作不當而帶來的內存錯誤
操作性:簡單易用,又不失功能強大
五、函數返回引用
引用作爲函數的返回值時,必須在定義函數時在函數名前加上“&”;用引用作爲函數的返回值的好處是在內存中不產生返回值的副本。引用作爲函數的返回值的幾種情況如下圖7所示:
圖7
- 圖7中的情況1,因爲d是局部變量,那麼它會在函數返回後被銷燬,main()函數的a就會成爲“無所指”的引用,程序會進入未知狀態。
- 圖7中的情況2,函數demo2()是以值方式返回到,返回時,首先拷貝temp的值給臨時變量。返回到主函數後,用臨時變量來初始化引用變量b,使得b成爲該臨時變量到的別名。由於臨時變量的作用域短暫(在C++標準中,臨時變量或對象的生命週期在一個完整的語句表達式結束後便宣告結束) ,所以b面臨無效的危險,很有可能以後的值是個無法確定的值。
- 圖7中的情況3,函數demo3()的返回值不產生副本,而是直接將全局變量temp返回給主函數,即主函數的賦值語句中的左值是直接從變量temp中拷貝而來(也就是說c只是變量temp的一個拷貝而非別名),這樣就避免了臨時變量的產生。尤其當變量temp是一個用戶自定義的類的對象時,這樣還避免了調用類中的拷貝構造函數在內存中創建臨時對象的過程,提高了程序的時間和空間的使用效率。
- 圖7中的情況4,函數demo4()中的靜態變量是存在全局存儲區的,所以和demo3()一樣,同樣可以提高了程序的時間和空間的使用效率。
- 不能返回函數內部通過new分配的內存的引用。雖然不存在局部變量的被動銷燬問題,但如果被返回的函數的引用只是作爲一個臨時變量出現,而沒有將其賦值給一個實際的變量,那麼就可能造成這個引用所指向的空間(有new分配)無法釋放的情況(由於沒有具體的變量名,故無法用delete手動釋放該內存),從而造成內存泄漏。因此應當避免這種情況的發生。
- 當返回類成員的引用時,最好是const引用。這樣可以避免在無意的情況下破壞該類的成員。
- 當函數返回全局變量的引用時,可以 被作爲賦值表達式的左值。