【C++】C++学习笔记之十三:类型转换函数

对于类型转换函数(convert function),共有两种形式:

  1. 当前类转换成其他类
  2. 其他类转换成当前类

当前类转换成其他类

语法:
operator () const {...}
语法特点:

  1. 没有返回值
  2. 没有参数
  3. 不改变类的数据成员(const),因为是转换。
class Fraction{
    public:
        //non-explicit-one-argument ctor 可以把int类型转换成该类类型实例
        Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) { }
        //转换函数,可以转成double
        operator double() const {
            return (double) (m_numerator / m_denominator);
        }
    private:
        int m_numerator; //分子
        int m_denominator; // 分母
};

//调用
Fraction f(3,5);
double d=4+f;       // 编译器首先会找全局的函数operator +(int, Fraction)->没有
                    // 编译器再找有没有可以把Fraction 转换成double的转换函数
                    // operator double() ->有

其他类转换成当前类(non-explicit-one-argument ctor 非明确的单实参构造函数)

把其他类转换成当前类,需要使用non-explicit-one-argument ctor(非明确的单实参构造)函数来配合实现。
语法特点:

  1. non-explicit
  2. 实参只有一个(形参可以多个)的构造函数
  3. 一个引导转换的操作符重载函数
    例如:
class Fraction{
    public:
        //non-explicit-one-argument ctor 可以把int类型转换成该类类型实例
        Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) { }
        //重载+操作符
        Fraction operator +(const Fraction & f)  {
            return Fraction(......);//根据分数加法规则构造临时的Fraction变量并传值的方式返回
        }
    private:
        int m_numerator; //分子
        int m_denominator; // 分母
};

//调用
Fraction f(3,5);
double d=f+4;       // 编译器首先会找全局的函数operator +(Fraction,int)->没有
                    //编译器再去Fraction的类内部找 operator+(int)的操作符重载函数->没有
                    // 编译器再找有没有可以把int转换成Fraction的转换函数->
                    //发现了non-explicit-one-argument ctor可以把int 转换成Fraction->
                    //然后再调用operator +(Fraction&) ->有

转换函数 vs non-explicit-one-argument ctor

如果以上两种方式同时存在,即Fraction即可以转换成double, 同时又支持int型数据转换成Fraction形式,则:

class Fraction{
    public:
        //non-explicit-one-argument ctor 可以把int类型转换成该类类型实例
        Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) { }
        //转换函数,可以转成double
        operator double() const {
            return (double) (m_numerator / m_denominator);
        }
        //重载+操作符
        Fraction operator +(const Fraction & f)  {
            return Fraction(f.m_numerator, m_denominator);//根据分数加法规则构造临时的Fraction变量
                                                          //并传值的方式返回
        }
    private:
        int m_numerator; //分子
        int m_denominator; // 分母
};

//调用
Fraction f(3,5);
Fraction f2 = f + 4;//错误 ->冲突,既可以把f转换成double,又可以把4转换成Fraction
double d = 4 + f;//正确

【C++】C++学习笔记之十三:类型转换函数_第1张图片
Paste_Image.png

explicit-one-argument ctor

对于上面类型转换的冲突,如果把构造函数前面加上explict关键字,就不会再有冲突。
因为explict常用语构造函数,表示必须显示调用构造函数才可以转换,即上面的例子,4不可以默认成Franction(4),如果需要转换必须明确调用才会发生转换。

class Fraction{
    public:
        //explicit-one-argument ctor 不可以把int类型转换成该类类型实例
        explict Fraction(int num, int den = 1) : m_numerator(num), m_denominator(den) { }
        //转换函数,可以转成double
        operator double() const {
            return (double) (m_numerator / m_denominator);
        }
        //重载+操作符
        Fraction operator +(const Fraction & f)  {
            return Fraction(f.m_numerator, m_denominator);//根据分数加法规则构造临时的Fraction变量
                                                          //并传值的方式返回
        }
    private:
        int m_numerator; //分子
        int m_denominator; // 分母
};

//调用
Fraction f(3,5);
Fraction f2 = f + 4;//正确 ->不会把4转换成Fraction(4),只会把f转换成double
double d = 4 + f;//正确

explicit关键字,一般就用于约束构造函数上(不可以隐式转换)

你可能感兴趣的:(【C++】C++学习笔记之十三:类型转换函数)