Declare non-member functions when type conversions should apply to all parameters.
- 我们之前说过,允许一个类进行隐式转换是一个糟糕的主意。但是当你设计一个数值类型的calss时允许隐式转换是合理的(例如整数转换为有理数)
- 只有当参数被列于参数列内,这个参数才是隐式转换的合格参与者。
//假设你这样开始你的Rational class
class Rational{
public:
Rational(int numerator=0,int den=1);//构造函数刻意不为explicit
//允许int-to-Rational
int numerator() const;//分子和分母大的accessor
int den() const;
private:
...
};
//你想对该类支持加减乘除等运算
//你可能要考虑 到底设计成member,non-member,non-friend函数等
//我们先看看member函数的情况
class Rational{
public:
...
const Rational operator*(const Rational& rhs)const;
};
//这个设计的确不错,下列调用都好
Rational oneEight(1,8);
Rational oneHalf(1,2);
Rational result=oneHalf*oneEight;//很好
result=result*oneEight;//很好
//但是加入你想进行混合运算
result=oneHalf*2;//很好
result=2*oneHalf;//错误
//这明显出问题了,乘法应该支持交换律的
//我们来看看operator*函数的调用就一目了然了
result=oneHalf.operator*(2);//很好
result=2.operator*(oneHalf);//错误
//为什么第一条语句通过了,而第二条却出错了
//其实第一条发生了隐式转换也就是进行了这样的构造调用
const Rational temp(2);
//传入int可以隐式的转换为Rational
//这就是我们不设置为explicit的原因
//我们想要通过编译
//可以用下列写法
const Rational operator*(const Rational& lhs,const Rational& rhs){
return ..
};
//这样就完美了
//再想想,设置为friend也是不科学的
//因为我们说过friend破坏了封装性
请记住
如果你 需要为某个函数的所有参数(包括被this指针指向的那个隐喻参数)进行类型转换,那么这个函数必须是一个non-member.



