引用的意義:
引用可以看作某個(gè)變量的“別名”,作為某個(gè)變量的別名而存在,因此在一些場合可以代替指針。
引用相對于指針來說具有更好的可讀性和實(shí)用性,能起到指針的部分作用,但是比指針安全。
引用在c++里面可以說是一把利器,引用用的好的話可以寫出非常精妙的程序。
引用的本質(zhì):
引用在C++中的內(nèi)部實(shí)現(xiàn)是一個(gè)常指針。
Type& name ?è Type* const name
C++編譯器在編譯過程中使用常指針作為引用的內(nèi)部實(shí)現(xiàn),因此引用所占用的空間大小與指針相同。
從使用的角度,引用會(huì)讓人誤會(huì)其只是一個(gè)別名,沒有自己的存儲(chǔ)空間。這是C++為了實(shí)用性而做出的細(xì)節(jié)隱藏。
我們在寫操作符重載的時(shí)候都是用引用作為函數(shù)的返回值,我們來看一段代碼:
int temp;int fun1(){ temp = 10; return temp;} int& fun2(){ temp = 10; return temp;} int main() { int a = 0, b = 0; // 1. 返回函數(shù)的普通類型 a = fun1(); // 2. 返回函數(shù)的引用 b = fun2(); // 3. 返回函數(shù)的引用去初始化一個(gè)新的引用 int &c = fun2(); cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; return 0;}// 編譯結(jié)果:a = 10 b = 10 c = 10
-
返回函數(shù)的普通類型
返回普通類型對象其實(shí)是返回這個(gè)對象的拷貝,c++其實(shí)會(huì)創(chuàng)建一個(gè)臨時(shí)變量,這個(gè)臨時(shí)變量被隱藏了,它會(huì)把temp的值拷貝給這個(gè)臨時(shí)變量,當(dāng)執(zhí)行語句“a = fun1();”的時(shí)候就會(huì)把臨時(shí)變量的值再拷貝給a,假設(shè)這個(gè)臨時(shí)變量是t,相當(dāng)于做了這兩個(gè)賦值的步驟:t = temp; a = t; -
返回函數(shù)的引用
返回引用實(shí)際返回的是一個(gè)指向返回值的隱式指針,在內(nèi)存中不會(huì)產(chǎn)生副本,是直接將temp拷貝給a,這樣就避免產(chǎn)生臨時(shí)變量,相比返回普通類型的執(zhí)行效率更高,而且這個(gè)返回引用的函數(shù)也可以作為賦值運(yùn)算符的左操作數(shù),但是這時(shí)候需要注意以下兩個(gè)問題:
1). 千萬別返回局部對象的引用,當(dāng)函數(shù)執(zhí)行完局部對象也就被銷毀,??臻g被釋放,從而返回的地址已經(jīng)不存在,導(dǎo)致后面執(zhí)行出錯(cuò)。
2). 返回堆區(qū)對象的引用,這種情況要特別注意,這時(shí)候返回函數(shù)的引用是作為一個(gè)臨時(shí)變量出現(xiàn),沒有將它賦值給一個(gè)實(shí)際存在的變量,那么這個(gè)堆區(qū)對象的內(nèi)存空間就沒有釋放,可能造成內(nèi)存泄漏。有人說這樣做是非法的?其實(shí)不是絕對的,只能說這種編程習(xí)慣很不好,這樣做只是容易造成內(nèi)存泄漏,只是我們要記住,我們在申請堆內(nèi)存以后必須記得去釋放這塊內(nèi)存。
- 返回函數(shù)的引用去初始化一個(gè)新的引用這個(gè)和前面一樣,都是不會(huì)產(chǎn)生副本,但是現(xiàn)在是用返回值去初始化一個(gè)引用聲明c,也就是說這時(shí)候變成了變量temp的別名,在c的生命周期內(nèi)temp是一直有效的,這樣做完全可以。