美文网首页
【C++】C++学习笔记之十三:类型转换函数

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

作者: Angeladoudou | 来源:发表于2016-10-30 00:01 被阅读0次

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

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

    当前类转换成其他类

    语法:
    operator <typename>() 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;//正确
    
    
    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++学习笔记之十三:类型转换函数

          本文链接:https://www.haomeiwen.com/subject/whgyuttx.html