条款21:必须返回对象时,别妄想返回其reference——120
程序员文章站
2022-07-12 17:51:04
...
文章目录
返回reference可能指向一个销毁的local stack对象 ——120
考虑下列程序:
class Rational{
public:
Rational(int numerator=0,
int denominator=1);
...
private:
int n,d;
friend const Rational operator*(const Rational& lhs,
const Rational& rhs);
};
如果定义一个local变量,就是在stack空间创建对象。将上面程序的operator* 函数写成如下:
const Rtional& operator* (const Rational& lhs, const Rational& rhs)
{
Rational result(lhs.n*rhs.n,lhs.d*rhs.d);
return result;
}
这样修改导致这样一个问题:首先你不免要调用Rational的构造函数,再者 result只是一个local stack变量,当调用函数结束时会被销毁,导致返回的reference指向一个空的对象。
返回reference指向一个Heap对象可能程序爱你内存泄漏——122
我们再将Rational中的operator* 函数改写成如下形式:
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational* result=new Rational(lhs.n*rhs.n,lhs.d*rhs.d);
return *result:
}
这种改写仍然存在付出一个“构造函数调用”的代价,另者,你使用new动态分配内存,又怎么使用delete释放资源呢?这常常很困难完成。
返回reference指向static对象仍不可取——122
再次改写:
const Rational& operator* (const Rational& lhs,const Rational& rhs)
{
static Rational result;
result=...;
return result;
}
这种写法像所有用上static对象的设计一样,这一个也立刻造成我们对多线程安全性的疑虑。再者,我们思考下列例子:
Rational a,b,c,d;
...
if((a*b)==(c*d)){
...
}
else{
...
}
毫不奇怪,表达式((a* b)==(c* d))总是为true。
一个“必须返回新对象”的函数的正确写法
inline const Rational operator* (const Rational& lhs,const Rational& rhs)
{
return Rational(lhs.n*rhs.n,lhs.d*rhs.d);
}
总结——124
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象而有可能同时需要多个这样的对象。条款4已经为“在单线程环境中合理返回reference指向一个local static对象”提供了一份设计实例。
推荐阅读
-
条款21:必须返回对象时,别勉强返回其reference
-
Effective C++条款21:必须返回对象时,别妄想返回其reference
-
条款21(二):必须返回对象时,别妄想返回其reference
-
条款21(一):必须返回对象时,别妄想返回其reference
-
条款21:必须返回对象时,别妄想返回其reference——120
-
Effective C++条款21:必须返回对象时,别妄想返回其引用
-
条款21:必须返回对象时,别妄想返回其reference
-
读书笔记《Effective C++》条款21:必须返回对象时,别妄想返回其reference
-
Effective C++ 详解条款21:必须返回对象时,别返回其reference
-
读书笔记《Effective c++》 条款21 必须返回对象时,别妄想返回其reference