Effective C++ 条款21
必须返回对象时。别妄想返回其reference
我们上节分析了对象引用传递的优点,如今说明函数返回引用对象带来的种种坏处。
先来一段代码:
class Rational{
public:
Rational(int numerator=0, int denominator=1);
……
private:
int n, d;
friend
const Rational operator*(const Rational& lhs,
const Rational& rhs);
};
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational result(lhs.n* rhs.n, lhs.d* rhs.d);
return result;
}
Rational a(1,2),b(3,4);
Rational &r=a*b;
大家看看以上代码有没有问题。非常显然此时的r是返回值的引用。非常明显对象本体已在operator*函数范围外被销毁。此时的r指向的对象已经被系统回收。程序非常easy出现错误。
那么,假设在函数体内动态创建对象呢?
例如以下代码:
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
Rational* result=new Rational(lhs.n* rhs.n, lhs.d* rhs.d);
return *result;
}
Rational w,x,y,z;
w=x*y*z;
上面代码有什么问题?
非常显然造成了内存泄露,两次调用 operator*函数,创建两个动态内存对象,可是最后却没有delete。
假设创建static 对象呢?
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
static Rational result;
result=……;
return result;
}
bool operator==(const Rational& lhs, const Rational& rhs);
Rational a, b, c, d;
……
if((a*b)==(c*d))
{
doSomething();
}
else
{
doOtherthing();
}
上面代码有什么问题?
答案是上面代码中(a*b)==(c*d)
的值一直为真。这是static的特性。所以。operator*的函数设计不合理,导致operator==出错。
说到如今总结一下。
非常简单就想题目所说函数必须返回对象时。别妄想返回其reference。那返回什么?非常明显返回对象的值而不是引用。