函數返回值、引用和指針的區別思考


學了引用、指針后,這些概念被教材拿去和函數攪在一起,於是使人感到很糊塗。涉及到函數返回的到底是值,引用還是指針的問題,其實就是函數返回的過程中和函數結束的過程中,哪些保留了,哪些復制了,哪些被處理掉的問題。我是這樣理解的:

首先說函數內的對象的保留和處理——當函數結束的時候,所有除了堆中的對象(不考慮傳入了什么樣的參數的前提下)之外的函數成員,全部都會被處理掉,無法保留;

其次,在返回的過程中,其實無論是引用,指針還是值,只要是跟在return后面的,都會以復制的方式來返回。但在這里,復制引用和指針並不代表復制它們所引用,所指向的對象(或內存對象),因此,復制它們只是復制了一個入口,這也就是這種復制方式更節省資源的原因。

最后,所有因為在函數的return后面而被作為返回復制出來的東西(包括值,引用和指針),都會在函數被調用的那一行執行結束后,被清理掉(唯有一種情況例外,就是被復制出來的是值,而值被“賦予”了一個引用)。因此,在被清理掉之前,要想完成傳遞,必須把它們賦予另一個變量或引用或指針。但是賦予變量或引用或指針,卻將會導致不同的結果。賦予變量的任何返回內容,都會被變量所保存,因為變量就是一塊實實在在的內存,能夠存東西。而賦予引用的返回對象,如果是引用的話,其實等於只保存了一個入口,但卻沒有保存下入口后面所有實實在在的內容。另一方面,將指針賦予指針會有兩種情況,如果指針指向棧中的對象,那么結果和引用賦予引用差不多,但如果指針指向堆中的對象,則可以看作是指針得到了繼承,一個指針通過它所繼承的另一個指針所記錄的地址,成功地找到了一塊實實在在的內存……

從表現和操作流程上來說,

第一種情況:函數如果返回的是值,那么在函數調用時,返回的值會被從函數中復制出來使用。當函數結束時,函數中的對應對象會被析構或結束,但復制出來使用的這一份仍然存在。

第二種情況:函數如果返回的是引用,那么在函數調用時,引用的對象不會被復制,只是引用本身被復制了。使用這個引用的問題是,當函數結束時,引用的對象也同時被析構,因此引用會變成空引用。由於不會被復制,因此除非被賦予一個新的對象,否則如果被賦予的對象是引用或是指針,則會導致引用和指針直接連向將要被析構的函數內的對象,於是,當函數內的對象被析構時,引用就會為空,而指針則雖然找到了地址,但卻因為對象的值被處理而出現失效的問題。

第三種情況:函數如果返回的是指針,那么在函數調用時,指針指向的對象不會被復制,只是指針本身被復制了一次,使用這個指針同樣會有指向的對象被析構的危險,但如果將這個指針賦予了另一個指針,且指針指向的對象在堆中的話,則可以繼續使用指針指向的堆中對象,因為這里對象的地址得到了繼承。但如果是棧中的對象,則會出問題,因為棧中的對象會在函數結束時被自動析構。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM