条款24:若所有参数皆需类型转化,请谓词函数采用non-member函数

来源:互联网 发布:应届生自我介绍知乎 编辑:程序博客网 时间:2024/05/22 07:42

还是前面那个有理数乘法的例子:

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指针)都有可能发生类型转化时,那么这个函数得放在非成员函数中。

原创粉丝点击