现在的位置: 首页 > 综合 > 正文

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

2014年01月16日 ⁄ 综合 ⁄ 共 796字 ⁄ 字号 评论关闭

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

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

抱歉!评论已关闭.