effective c++ 条款21: 必须返回对象时,别妄想返回其reference

RT,effective c++ 条款21: 必须返回对象时,别妄想返回其reference。

effective一直强调要养成用const reference的好习惯,以致于我经常在不该使用reference的时候也使用它,造成不良后果,这次读书笔记就是记什么时候不该返回一个reference。 下面是书上原话:

  考虑一个用以表现有理数的class,内含一个函数用来计算两个有理数的乘积:

class Rational{
public:
Rational(int num=0, int den=1);
private:
int n, d;  //分子和分母
friend const Rational operator*(const Rational& lhs, const Rational& rhs);
};
这个代码是以by value形式返回计算结果(一个对象),显然代价是会调用构造函数及析构函数,增加了不少成本,但是,如果我们改成传递reference,也就是这样:

class Rational{
public:
Rational(int num=0, int den=1);
private:
int n, d;  //分子和分母
friend const Rational& operator*(const Rational& lhs, const Rational& rhs);
};
假设我们在stack空间(系统自动分配内存) 里创建新对象,如下
friend const Rational& operator*( const Rational& lhs, const Rational& rhs)

{

Rational result(lhs.n*rhs.n, lhs.d*rhs.d);  //警告,糟糕的代码。

return result;

}

改成这样后在编译器里运行会提示warning:返回一个局部变量或临时对象。这是为什么呢?因为这个函数返回了一个reference指向result,但是result是个local对象(本地), 而local对象在函数退出前就被销毁了! 而且返回引用也避免不了调用析构函数的成本。


又假设我们在heap(程序员自己分配内存空间)空间创建函数对象,如下:

<p><span style="font-size:18px;">friend const Rational& operator*( const Rational& lhs, const Rational& rhs)</span></p><p><span style="font-size:18px;">{</span></p><p><span style="font-size:18px;">Rational *result = new Rational(lhs.n*rhs.n, lhs.d*rhs.d);  //警告,更糟的写法</span></p><p><span style="font-size:18px;">return *result;</span></p><p><span style="font-size:18px;">}</span></p>

我们还是得付出一个“构造函数调用”的代价,而且同时我们还面临了一个新的问题,谁该对着被你new出来的对象实施delete?这将很容易导致资源泄漏。


请记住:

绝不要返回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、付费专栏及课程。

余额充值