《深入理解C++11》笔记–显式转换操作符

上一篇:《深入理解C++11》笔记–右值引用:移动语义和完美转发
本编继续介绍第三章中的内容:显式转换操作符(显式转换自定义类型操作符)。
在介绍显式转换操作符之前先讨论一下C++的隐式转换,我们都知道很多时候C++会自动对类型进行转换,很多时候会比较方便,但是也会有一些问题,例如下面的例子:

class ExampleA{
public:
    ExampleA(int a = 0):data(a) {}
private:
    int data;
};

class ExampleB{
public:
    explicit ExampleB(int a = 0):data(a) {}
private:
    int data;
};

void printExampleA(ExampleB a){}
void printExampleB(ExampleB a){}

int main()
{
    ExampleA a1 = 0;
    ExampleA a2(0);

    ExampleB b1 = 0;   // 因为构造函数修饰为explicit,不能进行隐式转换
    ExampleB b2(0);

    printExampleA(0);
    printExampleB(0);  // 因为构造函数修饰为explicit,不能进行隐式转换
    return 0;
}

我们可以看到,ExampleB的构造函数因为用explicit修饰,所以不能隐式构造,而ExampleA可以隐式构造。printExampleA直接传入一个整形,也能运行,这里的问题就是:一般看到printExampleA(0);都会认为这个函数是打印整形的,容易引起误解。所以用explicit修饰有时候能有效减少歧义。
C++11把explicit扩展到了自定义的类型转换符上,以支持显式类型转换(显式转换自定义类型操作符)。

template <typename T>
class Ptr{
public:
    Ptr(T* t):p(t){}
    operator bool() const
    {
        if (nullptr == p)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
private:
    T* p;
};

int main()
{
    int a = 0;
    Ptr<int> ptra(&a);

    if (ptra)        // bool()转换
    {
        std::cout << "value pointer" << std::endl;
    }

    double b = 0;
    Ptr<double> ptrb(&b);
    std::cout << ptra + ptrb << std::endl;   // 输出2,因为实现了bool()转换,自动进行了转换(相当于1+1)

    return 0;
}

虽然ptra + ptrb能正常运行,但是实际上没有意义,也可能会导致误用,而对operator bool()进行explicit修饰就能阻止这种隐式转换。
显示转换主要是为了让代码更加明确和合理。
下一篇:《深入理解C++11》笔记–列表初始化

猜你喜欢

转载自blog.csdn.net/wizardtoh/article/details/80726537