您的位置:首页 > 编程语言 > C语言/C++

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

2015-02-04 16:49 405 查看
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对象而有可能同时需要多个这样的对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐