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

2022-08-24  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读