免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3066 | 回复: 9
打印 上一主题 下一主题

c = a + b; 操作符重载遇到的 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-26 17:27 |只看该作者 |倒序浏览
情况:

CNumber a, b;并且a, b已经初始化完毕。
CNumber的拷贝构造,以及操作符=和+=已经完成。

实际上,可以把 拷贝构造函数 和 操作符= 效率相当,
因为如果CNumber这个类对象同样的初始化,如果一个占用很多资源,那么另一个函数也会。

现在要计算 a + b 保存到c。
CNumber c = a + b;
或者
CNumber c;
add(a, b, c);

问题:
发现
c = a + b;
效率较差。想改进之,望高手指点。



  1. CNumber operator+(const CNumber &a, const CNumber &b)
  2. {
  3.     CNumber c = a; // 拷贝构造 1
  4.     c += b;
  5.     return c; // 拷贝构造 2
  6. }

  7. CNumber c = a + b; // 拷贝构造 3


复制代码



假设我这样:

  1. void add(const CNumber &a, const CNumber &b, CNumber &c)
  2. {
  3.   c = a; // 拷贝构造 1
  4.   c += b;
  5. }


  6. CNumber c; // 默认构造 2
  7. add(a, b, c);
复制代码


似乎add可一省去1次拷贝构造,

[ 本帖最后由 spibit 于 2007-7-26 22:15 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-07-26 17:35 |只看该作者
自己顶一下,
敢问有更好的方法吗?
不太喜欢因为使用方便导致性能有所下降。

论坛徽章:
0
3 [报告]
发表于 2007-07-26 17:40 |只看该作者
CNumber operator+(const CNumber &a, const CNumber &b)
{
    CNumber c = a; // 拷贝构造 1
    c += b;
    return c; // 拷贝构造 2
}

改成:
CNumber operator+(const CNumber &a, const CNumber &b)
{
    return a + b;
}

论坛徽章:
0
4 [报告]
发表于 2007-07-26 18:34 |只看该作者
需要了解在编译器实现上的 RVO 以及 NRVO 的概念。用它们作关键字搜索。

RVO - Return Value Optimization
NRVO - Named Return Value Optimization

[ 本帖最后由 whyglinux 于 2007-7-26 18:37 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-07-26 18:38 |只看该作者

回复 #3 converse 的帖子

仔细看看

论坛徽章:
0
6 [报告]
发表于 2007-07-26 20:33 |只看该作者
CNumber operator+(const CNumber &a, const CNumber &b)
{
    return a + b;
}

本来就是想实现CNumber类的加号操作符重载,所以实现里边怎么能用 a + b?  a、b是CNumber类型的,他们的“+“还没定义。

论坛徽章:
0
7 [报告]
发表于 2007-07-26 22:02 |只看该作者
CNumber operator+(const CNumber &a, const CNumber &b)
{
    return a + b;
}

这样是自己调用自己,死循环吧?


原帖由 whyglinux 于 2007-7-26 18:34 发表
需要了解在编译器实现上的 RVO 以及 NRVO 的概念。用它们作关键字搜索。

RVO - Return Value Optimization
NRVO - Named Return Value Optimization

我知道这个代码优化。但是这里行吗?

如果用了引用
c = a + b;
c不可预计。

因为 a + b 的结果就是引用了,此引用之实体在operator+重载函数退出时已经释放了,所以c就不知道是个什么东西了,

[ 本帖最后由 spibit 于 2007-7-26 22:21 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2007-07-26 23:34 |只看该作者
不好意思,刚刚没有仔细看题目,我的原意是省去创建一个临时的局部变量的过程。

假设CNumber这个类仅有一个成员变量是a,而operator+操作执行的就是a的相加,并且CNumber类中有一个构造函数可以传入初始化a参数的参数完成类对象的初始化,那么可以改些为:

CNumber operator+(const CNumber &a, const CNumber &b)
{
    return CNumber(a.a + b.a);
}

论坛徽章:
0
9 [报告]
发表于 2007-07-27 00:40 |只看该作者
原帖由 spibit 于 2007-7-26 22:02 发表

我知道这个代码优化。但是这里行吗?

如果用了引用
c = a + b;
c不可预计。

因为 a + b 的结果就是引用了,此引用之实体在operator+重载函数退出时已经释放了,所以c就不知道是个什么东西了,


优化是否可行取决于看编译器是否支持 RVO 或 NRVO 的实现。

关于后面的问题,或许你应该先了解一下 RVO 和 NRVO 是怎样实现的再说。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
10 [报告]
发表于 2007-07-27 09:26 |只看该作者
原帖由 converse 于 2007-7-26 23:34 发表
不好意思,刚刚没有仔细看题目,我的原意是省去创建一个临时的局部变量的过程。

假设CNumber这个类仅有一个成员变量是a,而operator+操作执行的就是a的相加,并且CNumber类中有一个构造函数可以传入初始化a参 ...

这个和原来的没啥区别的吧?也是构造一个临时变量,然后return出去

问题是:
    return c; // 拷贝构造 2
这个拷贝构造从何而来?

用operator+和add函数的效率是一样的,不过用add函数更丑陋,更难用而已。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP