Core List
1. operator* 的 member 函数和 non-member 函数实现
Class Rational {
public:
const Rational operator* (const Rational& rhs) const; // member 函数,第一个参数是 this 指针,因此两个参数只需要写一个即可
}
const Rational operator* (const Rational& lhs, const Rational& rhs) const; // non-member函数
2. member 函数 —— 类型转换
(1) 实例1:无类型转换
Rational oneEighth (1,8);
Rational oneHalf (1,2);
Rational result = oneEighth * oneHalf; // 正确,等价于 oneEighth.operator* (oneHalf);
(2) 实例2:类型转换
result = oneHalf * 2; // 正确,等价于 oneEighth.operator* (2);
const Rational temp(2);
result = oneHalf * temp;
注:
a. 这里发生了隐式类型转化,编译器知道传递一个 int,而函数需要一个 Rational;但它也知道调用一个 Rational 的构造函数,可以构造出一个 Rational 对象来。
b. 构造函数默认是non-explicit,如果声明为 explicit,则该语句不能生效,因为不会执行隐式类型转换。
(3) 实例3:类型转换
result = 2*oneHalf ; // 错误,等价于 2.operator* (oneEighth);
注:2 并非一个 Rational 类型,因此无 operator* 这个成员函数
结论:只有当参数被列于参数列内,这个参数才是隐式类型转换的合格参与者。地位相当于“被调用之成员函数所隶属的那个对象”—— 即 this 对象,不可隐式类型转换。
3. non-member函数 —— 类型转换
result = oneHalf * 2; // 正确,等价于 operator* (oneHalf, 2);
result = 2 * oneHalf; // 正确,等价于 operator* (2, oneHalf);
注:这里的 non-member 函数完全可以通过 class Rational 的public 接口实现,无需声明为 friend 函数。
结论:如果你需要为某个函数的所有参数(包括 this 指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个 non-member。