上一篇:《深入理解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》笔记–列表初始化