首先,看一个member函数实现两个有理数相乘的例子,
点击(此处)折叠或打开
- class Rational {
- public:
- Rational(int numerator = 0, int denominator = 1);//非explicit,可隐式类型的转换
- int numerator() const;
- int denominator() const;
- const Rational operator* (const Rational& rhs) const;
- private:
- int numerator;
- int denominator;
- };
- Rational oneHalf(1, 2);
- Rational result = oneHalf * 2; //通过, 这里的2隐式转换为Rational类型对象
- result = 2 * oneHalf; //不通过, operator* 操作对象必须为Rational类型,而这里只是int类型的2,所以编译不通过!!!
为什么第一条可以通过编译,而第二条却不能?
只有当参数被列于参数列表内,这个参数才是隐式类型转换的合格参与者!
当第二条result = 2 * oneHalf;编译失败后。编译器尝试寻找以下这般调用的non-member operator *(命名空间内或在global作用域内)。
result = operator* (2, oneHalf); //错误!因为本例中不存在这样一个接受int和Rational作为参数的non-member operator*。
现在,让operator* 成为一个non-member函数,允许编译器在每一个实参身上执行隐式类型转换:
点击(此处)折叠或打开
- class Rational {
- public:
- Rational(int numerator = 0, int denominator = 1);
- int numerator() const;
- int denominator() const;
- private:
- int numerator;
- int denominator;
- };
- 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; //ok
- result = 2 * oneFourth; //ok
此时的参数2均在参数列表之内,编译器对其隐式类型转换成Rational对象,编译成功!
**如果需要为某个函数的所有参数(包括this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member。