实例一:转换函数
转换函数不写返回类型,返回类型就是名称中的类型
class Fraction
{
public:
Fraction(int num,int den=1)
:m_numerator(num),m_denominator(den){}
operator double() const
{return (double)(m_numerator/m_denominator);}
private:
int m_numerator;
int m_denominator;
};
转换函数不可能改变class中的数据,所以需要加const关键字。
调用示例:
Fraction f(3,5);
double d=4+f; //调用operator double()将f转化为0.6
注:转化函数不是只能转化为基本类型,只要合理即可
实例二:non-explicit-one-argument构造函数
第二种思路:不写转换函数,而是对加法进行运算符重载
class Fraction
{
public:
Fraction(int num,int den=1)
:m_numerator(num),m_denominator(den){}
Fraction operator+(const Fraction& f){return Fraction(...);}
private:
int m_numerator;
int m_denominator;
};
调用示例:
Fraction f(3,5);
double d=4+f; //调用non-explicit ctor将 4转化为Fraction(4,1),然后调用重载+
non-explicit ctor可以被用来进行类型转换,与实例一的转换方向相反
实例三:歧义ambiguous(转换函数vsnon-explicit-one argument ctor)
实例一与实例二中的转换代码并存,这种情况下编译器将不知如何抉择
class Fraction
{
public:
Fraction(int num,int den=1)
:m_numerator(num),m_denominator(den){}
operator double() const
{return (double)(m_numerator/m_denominator);}
Fraction operator+(const Fraction& f){return Fraction(...);}
private:
int m_numerator;
int m_denominator;
};
是否会产生歧义取决于使用者如何使用,上述代码本身是没有问题的
实例四:explicit关键字
在之前代码的构造函数之前加上explicit关键字,约束该构造函数不能被当成转换函数使用
explicit关键字通常只在这种场景使用
加上explicit关键字后,上述代码在如下使用示例依然会报错
Fraction f(3,5);
double d=4+f;
报错原因是无法将4转换为fraction