class Rational
{
public:
Rational (int numrator = 0, int denominator =1 ); //构造函数不为explicit 允许隐式转换。
int numerator() const ; //分子的访问函数
int denominator() const; //分母的访问函数
private:
...
};
如果你想支持运算诸如加法,乘法。
class Rational
{
public:
...
const Rational operator * (cosnt Rational & rhs) cosnt ;
};
Rational oneEighth(1,8);
Rational oneHalf( 1, 2);
Rational result = oneHalf * oneEIghth; //没问题
result = result * oneEighth; //没问题
如果你想混合算术:
result = oneHalf * 2; //可以
retulr = 2* oneHalf; //错误!
也可以这样:
result = oneHalf.operator *(2); //没问题
result = 2.operator * (oneHalf); //错误!
因为oneHalf是一个内行operator * 函数的class对象,所以编译器调用该函数,然而整数2并没有相应的class,也就没有operator * 成员函数,
因为这里发生了所谓的隐式类型转换,编译器知到你正在传递一个int,而函数需要的是Rational:
相当于:
const Ratioanl temp(2);
result = oneHalf * temp;
在explicit构造函数时:
reuslt = oneHalf * 2; //错误!(explicit构造函数下,无法将2 转换为一个Rational。)
result = 2* oneHalf;
这很难让Rational class 支持混合式算术运算。
解决:
class Raional
{
... //不包括operator *
};
const Rational operator * ( const Rational & lhs ,const Rational & rhs )
{
return Rational ( lhs.numerator () * rhs. numerator (), lhs.denominator() * rhs.denominator());
}
Rational oneFourth(1,4);
Rational result;
result = oneFourth *2;
result =2 * oneFourth; //通过编译!
太多程序员假设如果一个“与某clas不相关”的函数不该成为一个member,就该时一个友元函数。member函数的反面时非成员函数,而非友元函数。