转换函数 (conversion function)
一. 概念
C++中定义了一种转化函数将本类型转化为其他类型。
二.声明
转化函数的声明格式:
operator <类型>() {}
注意:
- 转换函数无返回类型,因为<类型>已经指定了返回类型。
- 转换函数无入参。
- 通常转换函数中不会改变数据,因此我们将其设置为const函数。
- 转换函数仅能作为类的成员函数出现,当逻辑较为简单时,一般将其声明为inline函数。
三.代码实例及解析
class CFraction
{
public:
CFraction(int nNum, int nDen = 1) : m_numerator(nNum), m_denominator(nDen) {}
operator double() const { return (double)m_numerator / m_denominator; }
operator std::string() const { return std::to_string(m_numerator) + "/" + std::to_string(m_denominator); }
private:
int m_numerator; //分子
int m_denominator; //分母
};
int main()
{
CFraction f(3, 5);
double d = 4 + f;
std::string str = f;
std::cout << d << std::endl;
std::cout << str << std::endl;
return 0;
}
此例中我们仅分析 double d = 4 + f; 此行:
当程序执行到此行时,编译器首先会查找程序中是否存在参数为double, CFraction的全局+运算符重载函数,若有则执行该运算符重载函数,若无,则考虑将f转化为double类型参与运算,此时便会调用转换函数double()。
上述代码不存在运算符重载函数,因此会执行转化函数。
那么我们如何将其他类型转化为本类型呢?
目前来看有两种:1.使用构造函数,2.使用操作符重载函数。
四.一些扩展思考
(1) 可能会出现代码二义性的问题
class CFraction
{
public:
CFraction(int nNum, int nDen = 1) : m_numerator(nNum), m_denominator(nDen) {}
operator double() const { return (double)m_numerator / m_denominator; }
CFraction operator + (const CFraction &fraction)
{
// 如此写仅是为了简单,是错误的
return CFraction(m_numerator + fraction.m_numerator, m_denominator + fraction.m_denominator);
}
private:
int m_numerator; //分子
int m_denominator; //分母
};
int main()
{
CFraction f(3, 5);
CFraction d = f + 4;
return 0;
}
原因解析:
-
整形数字可以通过构造函数转化为CFraction类型,进而执行加法运算符重载函数。
-
f通过转换函数可以转换为double类型,之后再通过构造函数转化为CFraction类型,面对上述两种情况,编译器无法决定到底使用哪种方式。