如果需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member函数。
用书上的例子, 构造一个有理数的类, 在里面自定义一个构造函数, 并且重载*运算符:
using namespace std;
class Rational {
public:
Rational(int numerator = 0, int denominator = 1) {
cout << "Create" << endl;
}
const Rational operator* (const Rational& rhs)
{
Rational rat;
cout << "Operator * overloading" << endl;
return rat;
}
int numeator() const;
int denominator() const;
};
通过重载*运算符, 可以很好地实现两个对象的相乘:
#import <Cocoa/Cocoa.h>
#include "test.hpp"
int main(int argc, const char* argv[]) {
Rational one(1, 2);
Rational two(4, 5);
Rational three = one * two; // success
three = three * one; // success
}
但是如果你想支持混合运算, 利于一个Rational对象和一个int数相乘就会出现问题:
three = one * 2; // success
*后面接收的是Rational类型, 而我们传的是int类型的2. 为什么还可以success呢?
是因为发生了隐式类型转换.
编译器知道此时确实是传递了一个int,而函数需要的却是Rational;但编译器同时也知道,只要它调用Rational构造函数并赋予传递来的int,就可以构造出适当的Rational出来。换句话说,此时的调用动作在有点像以下的形式:
const Rational temp(2); //根据2建立一个暂时性的Rational对象
result = oneHalf * temp; //等同于oneHalf.operator*(temp)
然而当我们这样写构造函数
explicit Rational(int numerator = 0, int denominator = 1)
{
cout << "Create" << endl;
}
执行下行代码就会收到报错:Invalid operands to binary expression ('Rational' and 'int')
three = one * 2; // failed
接下来我们试试把int 2 放在*的前面
three = 2 * one; // failed
执行这行代码无论构造函数前面有木有explicit都会有Invalid operands to binary expression ('Rational' and 'int')的报错.
因为整数2并没有对应的class,也就没有operator* 成员函数。