对象而不是返回引用的原因
我们知道,函数的返回值或者参数传递,值传递的效率没有指针或者引用传递效率高,因为中间会有临时对象的产生和释放,所以,平时函数的返回值或参数能用引用或指针的尽量不要使用值传递;但是也不能看到函数函数返回或参数就想用引用和指针,就比如类的重载函数返回的就是类对象,也就是值传递,为什么不使用引用或指针呢?我们通过一个示例来分析一下:
class Rational
{
public:
Rational(int num,int cou);
.....
private:
int n,d;
const Rational operator*(const Rational& lns, const Rational& rhs)
{
Rational result(lns.n*rhs.n, lns.d*rhs.d);
return result;
}
};
重载函数乘内部的实现是在栈里定义一个局部的变量result作为乘法式的结果,这里返回的是一个局部变量,属于值传递,在传递的过程中会产生临时的对象,效率相对于返回指针和引用来说比价低,那为什么不反悔一个引用或者指针的形式呢?
const Rational* operator*(const Rational& lns, const Rational& rhs)
{
Rational *result = new Rational(lns.n*rhs.n, lns.d*rhs.d);
return *result;
}
};
如果返回指针的形式,必须在堆上申请一个Rational的内存,就如上面的代码一样,这里就会有一个问题,new出来的内存,该有谁来释放,如果没有释放,就会造成内存泄漏的问题;
Rational *w;
Rational x,y,z;
w = x*y*z;
上面的这段代码,连续调用了两次重载运算符乘,也就是申请了两次Rational的内存,根本没有合理的办法来delete两次内存,就会导致内存泄漏;
至于说重载运算符返回静态的Rational的办法,也是不可行,重载运算符需要考虑多线程安全问题,更加不好控制,所以还是使用值传递的形式返回Rational对象比较好;那确定完了使用值传递,就尽量减少中间临时对象的产生;
inline const Rational operator*(const Rational& lns, const Rational& rhs)
{
return Rational(lns.n*rhs.n, lns.d*rhs.d);
}
};
参考:
《More Effective C++ 35个改善编程与设计的有效方法》条款20
《 Effective C++ 改善编程与设计的55个具体做法》条款21