[問題] 物件可否call by value?

作者: Keitaro (動き出す時間...)   2014-06-20 01:43:13
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
VC
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
None
問題(Question):
請問物件、結構等複合型態,可否call by value?
我知道這問題可能很基本,但我問了朋友跟同事,沒有人能給我一個肯定的答案,
所以還是厚著臉皮上來請教各位先進了。
因工作關係開始寫MFC,開始學著C++的物件怎麼用。
但我一直疑惑著,複合型態是否真的無法使用call by value呢?
我知道像是陣列、結構、物件這種複合型態,一般來說都call by pointer/reference。
而複合型態的名稱,等同於它在記憶體裡面的起使位置。
那麼,如果我碰到底下這種狀況
"在function call產生的複合型態物件,要回傳到主程式中"
此時我不能用call by pointer/reference,
因為程式一離開function,產生的物件就消失了。
所以我猜想是否能寫成改為call by value,像底下這樣...
class CA;
int main()
{
CA obj_A = fun1();
...
}
CA fun1()
{
CA fun_obj = ...
return fun_obj;
}
我使用VC2008測試結果是可以的,結果正確。
那麼,complier是否在return物件時,把fun_obj的內容,完全拷貝給obj_A?
所以實際上,複合物件也是可以call by value?
當然我也想的到像這種情況,另一個作法是,先在main裡面把obj_A宣告,
然後用call by reference傳給fun1(),
使得fun1()直接將運算結果寫在obj_A的位址,改成像這樣...
class CA;
int main()
{
CA obj_A;
fun1(obj_A);
...
}
void fun1(CA& fun_obj)
{
fun_obj=...
}
但我想弄清楚,複合型態物件,其實是可以call by value的,是嗎?
謝謝各位。
作者: LPH66 (-6.2598534e+18f)   2014-06-20 01:44:00
當然可以, 只不過由於複製成本通常較 primitive 形態大所以一般不會用 call by value 傳進去另外你後面提的方法其實很接近一種叫做 RVO 的最佳化策略在有啟動 RVO 的時候, 編譯器會幫你把前一段程式變成後一段你寫的程式跟 RVO 的差別在於, RVO 會直接在 fun1 裡初始化那個外面的物件, 而你這段程式是初始化完了才傳參考進去關於 RVO 可看維基百科: http://ppt.cc/IOrL(註: RVO 是標準允許的最佳化, 即使可能因此不呼叫 ctor 等)
作者: kkkmode (kkk)   2014-06-20 02:06:00
物件用等號賦值或從函式以"值"返回時,都會呼叫copy constructor,你是指這個嗎?
作者: Killercat (殺人貓™)   2014-06-20 09:28:00
call by value要考慮shallow copy的問題,你的結構裡面要是有指標的話 很可能會拿到一個出了結構說錯 出了scope 就無效的指標其實我個人認為copy by value在某些層面上是個危險動作除非你能非常有把握的處理掉shallow copy造成的無效指標而把結構hold住的指標全部改成shared_ptr可以降低風險但是deep copy會演變成一個recursive copy的問題就是總之 我認為你可能沒想到那麼多,除非有必要否則多半還是儘量避免對結構by value的方式會比較好
作者: loveme00835 (髮箍)   2014-06-20 09:37:00
傳物件時,需要考慮一下是否其實是move語意或者你應該仔細分析 fun1() 做的是不是 ctor 在做的工作,如果是,那應該把程式碼放在 ctor 裡。如果不是,也許應該變成 member function 做一些操作的前置動作(非初始化)

Links booklink

Contact Us: admin [ a t ] ucptt.com