美文网首页
Effective c++学习笔记 (item15) 扩展 讨论

Effective c++学习笔记 (item15) 扩展 讨论

作者: 懒生活 | 来源:发表于2022-08-24 09:06 被阅读0次

    讨论隐式转换

    c++的隐式转换其实就是编译器发现本来某个位置期待的类型是A, 但是代码却给了类型B, 这种情况下,编译器会悄悄地调用隐式转换,让编译能够进行下去。好处是代码上比强制转换看起来更简洁更优雅。坏处就是编译器悄悄做的事情有可能是你不希望的。
    内置类型的隐式转换是编译器自带的。比如int到long,或者long到int,int 到bool等等的转换规则是编译器自带,用户无法自定义的。
    类对象的隐式转换是用户可以自定义的。

    例子1:

    比如下面的例子

    class AClass
    {
    
    };
    class BClass
    {
    public:
        string name;
    };
    void printBClass(BClass tt)
    {
        std::cout << tt.name << std::endl;
    }
    
    int main()
    {
        AClass a;
        printBClass(a);
    }
    

    编译器知道printBClass的入参应该是BClass类型,但是代码中给的a却是AClass类型. 所以编译器会悄悄地尝试执行printBClass(BClass(a)); 于是编译器会去找BClass(a)的实现. BClass(a)可以有两种理解, 一种理解是BClass类型的拷贝构造函数. 此时编译器会去BClass类中找是否有这种拷贝构造函数. 本例中没有. 另一种理解是a对象的操作运算BClass(), 此时编译器会去AClass中去找是否有类似的运算符定义. 本例中也没有.所以编译会报错,并中断.
    我们可以修改下例子, 通过自定义BClass(AClass a)的构造函数,来适配第一种理解:

    class AClass
    {
    
    };
    class BClass
    {
    public:
        BClass(AClass a)
        {
            name = "隐私转换来自BClass的构造函数";
        }
        string name;
    };
    void printBClass(BClass tt)
    {
        std::cout << tt.name << std::endl;
    }
    
    int main()
    {
        AClass a;
        printBClass(a);
    }
    

    我们也可以修改下例子,通过自定义AClass的运算符BClass(),来适配第二种理解

    class BClass
    {
    public:
        string name;
    };
    class AClass
    {
    public:
        operator BClass()
        {
            BClass tmp;
            tmp.name = "隐私转换来自AClass的运算符操作";
            return tmp;
        }
    };
    
    void printBClass(BClass tt)
    {
        std::cout << tt.name << std::endl;
    }
    
    int main()
    {
        AClass a;
        printBClass(a);
    }
    

    那如果我即定义AClass的运算符BClass(), 又定义了BClass(AClass a)的构造函数, 编译器就会疑惑不知道用那个去做隐式转换的规则, 会报错并中断.

    例子2:

    对于下例的if(a), 编译器期望if里面是个bool类型,但是代码给定的a却是的AClass类型,所以编译器会悄悄的尝试执行if(bool(a)), 同例子1相同, 编译器对bool(a)一样有两种解读. 但是bool是内置类型,不可能自定义bool类型的拷贝构造函数.所以对于这个例子,只能通过定义AClass的bool()运算符的方式实现隐式转换.

    class AClass
    {
    public:
    };
    
    int main()
    {
        AClass a;
        if (a)
        {
            ;
        }
    }
    

    只能通过定义AClass的bool()运算符的方式实现隐式转换

    class AClass
    {
    public:
        operator bool()
        {
            return true;
        }
    };
    
    int main()
    {
        AClass a;
        if (a)
        {
            std::cout << "自定义隐式转换成功" << std::endl;
        }
    }
    

    参考如下文章:
    彻底理解c++的隐式类型转换 - apocelipes - 博客园 (cnblogs.com)
    Overload resolution - cppreference.com
    Implicit conversions - cppreference.com

    相关文章

      网友评论

          本文标题:Effective c++学习笔记 (item15) 扩展 讨论

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