class Rational
{
public:
Rational(int x, int y) : m_x(x), m_y(y){}
//返回const是属于类型保护,friend修饰,以后条款详说
friend const Rational operator + (const Rational &lhs, const Rational &rhs)
{
Rational temp(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y); //还有更好的做法
return temp;
}
private:
int m_x;
int m_y;
}; 实现+号重载,我们采用return value,根据前面条款,返回value会调用一系列拷贝构造函数,析构函数的成本,于是我们修改为return reference friend const Rational& operator + (const Rational &lhs, const Rational &rhs)
{
Rational temp(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y); //还有更好的做法
return temp;
}
friend const Rational operator + (const Rational &lhs, const Rational &rhs)
{
return Rational(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y); //标准做法
} 分析下:第一种做法是创建临时对象,调用构造函数初始化,返回时调用拷贝构造函数初始化存放返回值的外部变量,最后调用析构函数。而第二种是编译器直接创建临时对象并初始化外部变量,省去调用拷贝构造函数和析构函数。 friend const Rational& operator + (const Rational &lhs, const Rational &rhs)
{
return *(new Rational(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y));
}看下面调用Rational x(1,2), y(3, 4), z(5, 6); Rational r = x + y + z;调用了两次operator +,两次new调用分配内存,但没有合理的方法delete内存,因为没有合理的方法取得返回reference的那个指针,导致内存泄露。
friend const Rational& operator + (const Rational &lhs, const Rational &rhs)
{
static Rational sRational(lhs.m_x + rhs.m_x, lhs.m_y + rhs.m_y);
return sRational;
}
Rational x(1,2), y(3, 4), z(5, 6), w(7, 8);
if ((x + y) == (z + w)) {
cout<<"equal\n";
} 因为+号返回引用,而引用执行的对象时static,两次的+号返回reference其实是指向同一个对象,那==值判断永远相等。条款21:必须返回对象时,别妄想返回其reference,布布扣,bubuko.com
原文地址:http://blog.csdn.net/hualicuan/article/details/27640713