C++面向对象编程

vichal 2011-12-26 02:26:20
当一个函数需要返回一个对象时,选择返回对象,还是利用参数返回。那个更加效率。

例如

class Test
{
public:
Test():mvalue(0){};
Test(const& rhs){mvalue = rhs.mvalue;};

private:
int mvalue;
}


Test foo();
void foo(Test& test);

上面的两个foo那个跟好一些
...全文
158 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
duruosu212 2011-12-27
  • 打赏
  • 举报
回复
都是高手啊,学习了。
卡卡_苏米 2011-12-27
  • 打赏
  • 举报
回复
难道不是引用高一些么?
vichal 2011-12-27
  • 打赏
  • 举报
回复
我也是知道作为参数效率要高的,但是总觉得如果在任意需要返回对象的情况下都用参数返回值也不对。那位能不能告诉我什么时候该用返回值什么时候用参数,为什么。
z_terry 2011-12-27
  • 打赏
  • 举报
回复
引用:
Test t1 = foo();//优化时直接将对象构造在t1的内存区处
Test t2;
t2 = foo();//这里必须先将返回值对象构造在返回值对象存储区(一般是在主调函数的栈帧上)

用户代码层面确实是构造了多次,但是实际生成的代码只会构造一次,即便是优化选项没有打开。返回值优化几乎是所有编译器都默认支持,在debug模式下也被打开的(VS2008下验证过,其它编译器不详)。
we_sky2008 2011-12-26
  • 打赏
  • 举报
回复
至于大家说的一样,我觉得可能是有些人看过《深度探索C++对象模型》,
里面是说过,
Test foo();
在实现时编译器会改写为如下伪码
void foo(Test __result);
但是,要注意的是,编译器在改写代码时本质上是传递一个未使用过的空间的地址,
而用户传递引用参数时,这个引用参数所绑定的对象是应该已经存在的
编译器是编译器,用户代码是用户代码,两个不相同的
we_sky2008 2011-12-26
  • 打赏
  • 举报
回复
完全不同的两个事物,
返回对象时,这个对象必须被构造,或者被构造在返回值对象存储区或者接收者对象(返回值优化)


Test t1 = foo();//优化时直接将对象构造在t1的内存区处
Test t2;
t2 = foo();//这里必须先将返回值对象构造在返回值对象存储区(一般是在主调函数的栈帧上)


而是用引用参数时,因为参数是引用,你在调用这个函数前就必须存在这么一个对象,你在函数体内做到的只是修改这个对象而已
z_terry 2011-12-26
  • 打赏
  • 举报
回复
效率都一样,生成一样的代码,理解上可以搜索了解一下返回值优化,不过反汇编最真实。
如此美丽的你 2011-12-26
  • 打赏
  • 举报
回复
[Quote=引用楼主 vichal 的回复:]
当一个函数需要返回一个对象时,选择返回对象,还是利用参数返回。那个更加效率。

例如

class Test
{
public:
Test():mvalue(0){};
Test(const& rhs){mvalue = rhs.mvalue;};

private:
int mvalue;
}


Test foo();
void foo(Test&……
[/Quote]

看反汇编的话,你会发现是一样的。
孤舟 2011-12-26
  • 打赏
  • 举报
回复
为啥不用
Test *foo();和第2个 没啥区别
丰清云淡 2011-12-26
  • 打赏
  • 举报
回复
首先纠正一下你定义类Test中的错误
class Test
{
public:
Test():mvalue(0){};
/*Test(const& rhs){mvalue = rhs.mvalue;};*/
Test(const Test& rhs)
{
mvalue = rhs.mvalue;
}

private://后面的讲解,基于mvalue为public,否则要提供一个访问成员变量mvalue的接口
int mvalue;
};//注意'}'后面的';'


然后,你的问题是在函数中将对象作为函数返回值和作为输出参数之性能比较:
首先我们看将对象作为函数返回值,例如oper函数
Test oper()
{
Test test;
test.mvalue = ...;
return test;
}
这种情况下,在函数内部够早了Test类对象test,但是在执行return test语句时,由于test的作用范围仅在{和}之内,编译器会构造一个临时对象(temporary object),然后调用拷贝构造将test完整复制一份给临时对象,总的个来说,在执行这个函数时构造了两次对象。

然后我们看将对象作为输出参数,例如
void oper(Test &test)
{
test.mvalue = ...;
}
Test test;
oper(test);
在执行oper函数之前,构造了一次对象,在oper函数内部,只做成员变量的存取。

现在,你的问题已经很清楚了,在上述情况下将对象作为输出参数性能较作为函数返回值时高。

希望对你有所帮助,呵呵 。
薛定谔之死猫 2011-12-26
  • 打赏
  • 举报
回复
如果对象体积不大的话都差不多,第一种要实现拷贝构造函数,第二种是引用参数,不是把函数体内的对象带出来,而是吧函数体内的对象拷贝到参数的对象中来~
iamnobody 2011-12-26
  • 打赏
  • 举报
回复
第二个更有效率一些,但是更加麻烦,如果这个对象的复制构造不是重量级的就应该考虑用第一种
FingerStyle 2011-12-26
  • 打赏
  • 举报
回复
效率的话 是第二种
bmowker 2011-12-26
  • 打赏
  • 举报
回复
我理解都是一样的

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧