还是前面那个有理数乘法的例子:
class Rational
{
public:
Rational(int numerrator = 0, int denominator = 1):n(numerrator),d(denominator){}
const Rational operator*(const Rational& rhs)
{
n = n * rhs.n;
d = d * rhs.d;
return *this;
}
double getVal()
{
double result = (double)n / double(d);
return result;
}
private:
int n;//分子
int d;//分母
};那么假如我们调用:
Rational t1(1,2);
Rational t2(1,2);
Rational t3;
t3 = t1 * 3;是没有问题的,但是如果调用t3 = 3 * t1;编译就不会通过了。这是我们不想看到的情况,因为我们都知道乘法是满足交换律的。问题出在哪呢?其实t3 = t1 * 3;这句代码中,编译器知道*操作的操作数是一个Rational,所以会调用构造函数把3初始化为一个Rational类的对象,(前提是你的构造函数不是explict)然后再调用Rational操作。而对于 3 * t1,适当做operator*(3,t1)来处理的,可是并不存在一个这样的函数,所以就会报错了。
这个问题的解决办法其实也很简单,将operator*声明为非成员函数:
Rational operator*(const Rational &lhs,const Rational &rhs)
{
Rational result(lhs.n*rhs.n,lhs.d*rhs.d);
return result;
}再将它设为友元,然后不管3在前还是在后,遇到3时总会把它变成一个Rational类的对象。
总之,如果函数的参数(包括this指针)都有可能发生类型转化时,那么这个函数得放在非成员函数中。
1090

被折叠的 条评论
为什么被折叠?



