當函式返回類物件的時候,c++編譯器會進行返回值優化
返回值優化(return value optimization,縮寫為rvo)是c++的一項編譯優化技術。即刪除保持函式返回值的臨時物件。這可能會省略兩次複製建構函式,即使複製建構函式有***。[1]
[2]典型地,當乙個函式返回乙個物件例項,乙個臨時物件將被建立並通過複製建構函式把目標物件複製給這個臨時物件。c++標準允許省略這些複製建構函式,即使這導致程式的不同行為,即使編譯器把兩個物件視作同乙個具有***。[3]
#includestructcc
(constc&
)};cf
()int
main
()
對於函式返回類物件,一種實現辦法是在函式呼叫語句前在stack frame上宣告乙個隱藏物件,把該物件的位址隱蔽傳入被呼叫函式,函式的返回物件直接構造或者複製構造到該位址上。[4]
例如:
structdata
;dataf()
;// generate result
return
result;}
intmain
()
可能產生的**如下:
structdata
;data*f
(data
*_hiddenaddress);
// copy result into hidden object
*_hiddenaddress
=result
;return
_hiddenaddress;}
intmain
()
這引起了data
物件被複製兩次。
另一種技術是命名返回值優化(named return value optimization,nrvo)。[5]
nrvo去除了基於棧的返回值的構造與析構。雖然這會導致優化與未優化的程式的不同行為。
structdata
;voidf(
data*p
)int
main
()
大部分c++編譯器均支援返回值優化。[1]
[6][7]
在某些環境下,編譯器不能執行此優化。乙個常見情形是當函式依據執行路徑返回不同的命名物件,或者命名物件在asm內聯塊中被使用:[4]
[6][8]
#includestructcc
(constc&
)inti;
};cf(
bool
cond
=false
)int
main
()
若想看到不進行返回值優化,那麼可以在編譯的時候新增-fno-elide-constructors,來禁止編譯器來進行返回值優化
其他資料:
c 返回乙個物件 使用C 臨時物件的後果
但是!我就是想看看這麼做的糟糕後果是什麼!先要搞清楚什麼是臨時物件,這裡我參考 more effective c 99頁定義。真正的臨時物件是在原始碼中不可見的,是棧上的 沒有名字的物件。與函式內定義的臨時物件有根本差別。第一種 當觸發隱式型別轉換時 例如 統計ch在str 現的次數 size t ...
在必須返回乙個物件時,不要去嘗試返回乙個引用
一旦程式設計師把注意力都轉向了物件傳值方式隱含的效率問題 參見第 20 條 時,許多人都變成了極端的 改革運動者 他們對傳值方法採取斬草除根的態度,在他們不屈不撓追求傳遞引用方式的純粹性的同時,他們也犯下了致命的錯誤 有時候傳遞的引用所指向的物件並不存在。這決不是一件好事情。請看下面的示例,其中的 ...
c 返回乙個陣列
bqg s complexity analysis 最近遇到乙個很不一般的事情,返回乙個陣列時,我們可以直接返回它的首位址,但是如果呼叫兩次以上,返回的數值就是有問題的了。呼叫兩次js 函式,分別用a b陣列存放返回的陣列值,但是接收到返回的數值居然和我返回前存放的數值不一樣。及改善 include...