Effective C++条款21:必须返回对象时,不要返回reference

  • 如果返回的对象为reference有什么问题 
  • 有这样的有理数相乘的例子
class Rational
{
public:
    Rational(int numerator = 0, int denominator = 1);
private:
    int n, d; //分子和分母
    // 返回对象为reference
    friend const Rational& operator*(const Rational& lhs, const Rational& rhs);
};

那么operator*内的函数需要在heap或stack上新建Rational对象来返回。

  • 在heap上新建
friend const Rational&
    operator*(const Rational& lhs, const Rational& rhs)
{
    Rational result(lhs.n*rhs.n, lhs.d*rhs.d);
    return result; //局部变量result在退出函数已经被销毁,这是最常见的错误写法
}
  • 在stack上新建
friend const Rational&
    operator*(const Rational& lhs, const Rational& rhs)
{
    Rational *result = new Rational(lhs.n*rhs.n, lhs.d*rhs.d);
    return *result;  //返回的对象值
}

返回的是new出来的对象,由于是refence类型,故不会有额外的构造,析构函数的开销,但是谁,在哪里去delete呢?就算可以不忘记delete,但也无法保证不会有内存泄漏的操作。比如下面这样

Rational w, x, y, z;
w = x*y*z; //相当于operator*(operator*(x,y),z);

operator*(x,y)执行了一次new 操作, operator*(operator*(x,y),z);也执行了new操作,但现在只有w对象是可以拿到的,那么只能delete由operator*(operator*(x,y),z); new出来的对象,那operator*(x,y) new出来的对象就没有被delete,这不就内存泄露了嘛

  • 返回static 对象
friend const Rational&
    operator*(const Rational& lhs, const Rational& rhs)
{
    static Rational result;
 
    //result=...; 
 
    return *result; //返回static对象
}

第一个问题就是:多线程不安全,其次就是下面这种写法永远为真

//判断两个对象相等否
bool operator==(const Rational& lhs,const Rational& rhs);
 
int main()
{
    Rational a,b,c,d;

    if((a*b)==(c*d)){ //永远为真 等价于if(  operator==(operator*(a,b), operator*(c,d))  )
 
    } else{
 
    }
}

比如先调用operator*(a,b),那么会有一个static Rational result;再调用operator*(c,d),那么由于局部static的特性:不会再产生新的static Rational result;用的是之前operator*(a,b)的那个static对象,所以if((a*b)==(c*d))永远为真。。。

总之: 返回的对象为reference会带来很多问题,直接不要返回reference就可以了

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值