条款 21 :必须返回对象时,别妄想返回其reference
Don’t try to return a reference when you must return an object.
- 任何时候你看到一个reference声明式,你都应该问自己,他的另一个名称是什么?因为他一定是某物的另一个名称。
- 任何函数如果想要返回一个引用指向一个local对象,那将带来许多错误
//我们考虑下列代码
class Rational{
public:
Rational(int numerator=0,in denominator=1);
...
private:
int n,d;
friend const Rational operator*
(const Rational& lhs,const Rational& rhs);
};
//这个版本的operator*是以by-value方式返回一个计算结果
//这回花费一些构造时间,但是使用没有问题
//假设我们进行以下调用
Rational a(3,5);
Rational b(7,5);
Rational c=a*b;//c因该是21/25
//这个调用是没有问题的
//但是加入你想返回一个引用,这是不切实际的
//也就是说你想再调用operator*之前就存在一个既有的对象来存放结果
//倘若你非要这么写
const Rational& operator*
(const Rational& lhs,const Rational& rhs){
Rational result(lhs.n*rhs.n,lhs.d*rhs.d);
return result;
}
//上面这是个个及其糟糕的代码。
//居然想要返回一个局部对象
//或许你会想把要返回的对象那个放在堆里
//但是,仔细想想,放在了堆里我们如何管理?
//鉴于上述问题,返回一个引用指向堆里的对象也是不可取的
//或许你还会想返回一个static对象的引用。
//这就更糟糕了。
//细想,假设我们进行以下调用
if((a*b)==(c*d));
//猜猜会发生什么,if()条件永远为真
//因为返回的是应用,且指向的同一个static对象
//所以对于一个必须返回对象的函数最简单的处理方法就是让他返回对象
//如下
const Rational operator*(const Rational& lhs,Rational& rhs){
return Rational(lhs.n*rhs.n,lhs.d*rhs.d);
}
请记住
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个local static对象而有可能同时需要多个这样的对象。