Effective C++读书笔记之必须返回对象时,别妄想返回其reference

      上节我们说使用pass-by-reference-to-const比pass-by-value效率高,可是有时候为了得到正确的结果,我们必须使用pass-by-value。如果一味的使用pass-by-reference-to-const,可能会犯下一个致命的错误:开始传递一些reference指向其实并不存在的对象。
 下面的例子说明了,在特定的情况下,使用pass-by-reference-to-const可能会出的错。
 考率一个用以表现有理数的class,内含一个函数用来计算两个有理数的乘积。
 class Rational {
 public:
  Rational (int numerator = 0, int denominator = 1); //构造函数 同时也是default构造函数
  ....
 private:
  int n,d;
  friend const Rational operator* (const Rational& lhs, const Rational& rhs);
 };
 这个版本的operator*系以by value方式返回其计算结果(一个对象)。这个函数会有调用构造函数和析构函数的代价,如果使用reference就没有这些代价,现在我们分析一下,这样做可不可以。
      使用reference必须之前先创建对象,函数创建对象有两个办法:在stack空间或在heap空间上。如定义一个local变量,就是在stack空间创建对象。根据这个策略的operator*如下:
 const Rational& operator* (const Rational& lhs, const Rational& rhs)
 {
  Rational result(lhs.n * rhs.n, lhs.d * rhs.d);
  return result;
 }
 有两个问题:
 1) 这个方式在生成result时,使用了构造函数,没有减少开销
 2) 这个reference指向一个local对象result,而local在函数退出前被销毁了。所以函数返回了一个指向空的reference。这会造成严重的结果。
 在heap内构造一个对象,并返回reference指向它。Heap-based对象由new创建。根据这个策略的operator*如下:
 const Rational& operator* (const Rational& lhs, const Rational& rhs)
 {
  Rational* result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d);
  return *result;
 }
 也有有两个问题:
 1) 它还是会付出一个构造函数调用代价
 2) 谁该对被你new出来的对象实施delete。造成了资源泄露。
 所以在这种情况下,为了得到正确的结果,必须使用pass-by-value,虽然需要付出一些代价。代码如下:
 inline const Rational operator* (const Rational& lhs, const Rational& rhs)
 {
  return Rational result(lhs.n * rhs.n, lhs.d * rhs.d);
 }
 总结:
 绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象而在可能同时需要多个这样的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值