[问题] 物件可否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