函式千萬不要返回區域性物件的引用或指標
區域性變數在函式裡面,當函式執行結束後將釋放區域性變數,如果返回引用或批針這個時候引用或指標指向所指向的記憶體空間已經釋放。指標和引用將是垂懸指標。很危險!
但是如果返回的「區域性變數」是堆中的記憶體值就可以返回了
c++函式為什麼要使用引用?
c語言之中大量利用指標作為形參或者函式返回值,這是由於值拷貝會有很大的消耗(比如傳入傳出乙個大的結構體)。所以在c++之中使用引用作為函式引數和返回值的目的和使用指標是一樣的。而且形式上更加直觀,所以c++提倡使用引用。
1)返回非引用型別:函式的返回值用於初始化在跳出函式時候建立的臨時物件。用函式返回值來初始化臨時物件與用實參初始化形參的方法是一樣的。如果返回型別不是引用的話,在函式返回的地方,會將返回值複製給臨時物件。且其返回值既可以是區域性物件,也可以是表示式的結果。
2)返回引用:當函式返回引用型別的時候,沒有複製返回值,而是返回物件的引用(即物件本身)。
函式返回引用:實際上是乙個變數的記憶體位址,既然是記憶體位址的話,那麼肯定可以讀寫該位址所對應的記憶體區域的值,即就是「左值」,可以出現在賦值語句的左邊。
3) 函式返回引用的時候,可以利用全域性變數(作為函式返回),或者在函式的形參表中有引用或者指標(作為函式返回),這兩者有乙個共同點,就是返回執行完畢以後,變數依然存在,那麼返回的引用才有意義。
1、引用其實本質就是位址
2、當函式返回值型別為引用時,一般就用引用型別去接收,或者就使用了引用的作用,如果用非引用型別接受,就等於將函式返回的引用的資料值,複製給了該接收物件,和函式返回非引用型別是一樣的效果。
3、當函式返回值型別為引用時,如果不考慮接收問題,則有乙個特性,則是可以直接操作該函式返回的引用,如放在=左面 +=等.
小結:
(1)使用引用當作函式引數和返回值,效率更高。
(2)函式返回的物件引用,必須在呼叫函式前就已經存在,不允許返回區域性變數的引用!
(3)當不希望返回的物件被修改的時候,可以新增const。
class
node
//拷貝建構函式
//node(const node &n)
//};
node& getnode()
intmain()
在上面的**中,最後能夠輸出正確的值,然而在函式getnode()中,str是乙個區域性的物件,記憶體空間在棧上,當函式退出時,str的記憶體空間被**,這是在高階語言的層面上講的。但是為什麼最後的結果是正確的?原因就是node newnode=getnode();這句呼叫的是預設的拷貝建構函式,如果是自己重新重寫拷貝建構函式,而不用預設的拷貝建構函式,那麼這段**就絕對有問題,最後輸出的是未定義的數。
然而,為什麼用預設的拷貝建構函式就能夠正確的輸出最後的值呢?
通過呼叫這段**的反彙編我們可以看到:
node newnode=getnode();
013215fe call getnode (1321019h)
01321603 mov ecx,dword ptr [eax] //eax呼叫getnode 函式返回的棧的棧頂指標
01321605 mov dword ptr [newnode],ecx
01321608 mov edx,dword ptr [eax+4]
0132160b mov dword ptr [ebp-10h],edx //這句為double的a資料成員賦值
0132160e mov ecx,dword ptr [eax+8]
01321611 mov dword ptr [ebp-0ch],ecx //這句為int的b資料成員賦值
01321614 mov edx,dword ptr [eax+0ch]
01321617 mov dword ptr [ebp-8],edx //這句為char的c資料成員賦值
cout<
也就是說直接呼叫預設的拷貝建構函式(或者預設的賦值函式),函式返回,在函式中的區域性變數的銷毀,其實在棧中只是棧頂的指標的移動,仍然還是可以為其賦值的。
然而:node &newnode=getnode();
cout<
對於**,newnode是對getnode函式的
引用,當函式結束時,其實是已經吧區域性物件str銷毀了,但是由於輸出的結果仍然還在堆疊中,所以第乙個能夠輸出正確的值,第二個是由於堆疊已經被其他的數覆蓋,所以不能輸出正確的值,而且這個物件也不能為其賦值,因為它的記憶體空間已經不存在了.
c 返回函式區域性物件的引用
在上面的 中,最後能夠輸出正確的值,然而在函式getnode 中,str是乙個區域性的物件,記憶體空間在棧上,當函式退出時,str的記憶體空間被 這是在高階語言的層面上講的。但是為什麼最後的結果是正確的?原因就是node newnode getnode 這句呼叫的是預設的拷貝建構函式,如果是自己重新...
C 過載 使用引用返回函式值
參考 include include using namespace std class string copy construct string const string other string string string const char s 建構函式定義 string string op...
返回函式的函式
廖雪峰python課程裡的 作業的兩種實現方法 1.def createcounter a 0 def counter nonlocal a nonlocal 函式是 引用外部函式 的函式 a 1 a 1等同於a a 1 return a return counter countera create...