1. 只有当参数位于参数列内, 这个参数才是隐式类型转换的合格参与者。
类中二元操作符重载的时候, 左边操作数会以this指针传入, 右边操作数会以参数列的参数传入。
所以, 如果你需要为某个函数的所有参数(包括 this 指针所指的那个隐喻参数)进行类型转换,
那么这个函数必须是个non-member函数。
案例: 实现 Rational 的混合运算
#include <iostream>
using namespace std;
class Rational
{
public:
// 构造函数刻意不为 explicit , 允许 int-to-Rational 隐式转换
Rational(int numerator = 0, int demominator = 1)
{
this->m_numerator = numerator;
this->m_demominator = demominator;
}
// const 类型返回, 可以保证不会有把表达式进行赋值的异常操作(a*b=c)
// 直接返回值, 可以保证多个操作对象的需要((a*b) == (c*d))
const Rational operator*(const Rational& rhs)
{
return Rational(this->m_numerator * rhs.m_numerator,
this->m_demominator * rhs.m_demominator);
}
// const 对象只能访问 const成员函数
int numerator() const
{
return m_numerator;
}
int demominator() const
{
return m_demominator;
}
private:
int m_numerator;
int m_demominator;
};
int main()
{
Rational one(1,2);
Rational result(3,4);
result = one * 3; // 可以正常,根据运算符转换为 one.operator*(3) , 3为参数列, 3可以通过隐式构造函数转换
result = 3 * one; // 编译报错, 根据运算符转换为 2.operator*(one) , one为参数列, 无法识别
return 0;
}
解决方法: 采用 non-member函数, 将左右作为均以参数列的形式传入, 那么就可以进行隐式转换
#include <iostream>
using namespace std;
class Rational
{
public:
// 构造函数刻意不为 explicit , 允许 int-to-Rational 隐式转换
Rational(int numerator = 0, int demominator = 1)
{
this->m_numerator = numerator;
this->m_demominator = demominator;
}
// const 对象只能访问 const成员函数
int numerator() const
{
return m_numerator;
}
int demominator() const
{
return m_demominator;
}
private:
int m_numerator;
int m_demominator;
};
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.demominator() * rhs.demominator());
}
int main()
{
Rational one(1,2);
Rational result(3,4);
result = one * 3; // 可以正常,根据运算符转换为 operator*(one , 3) , 3为参数列, 3可以通过隐式构造函数转换
result = 3 * one; // 可以正常, 根据运算符转换为 operator*(3, one) , 3为参数列, 3可以通过隐式构造函数转换
return 0;
}