c++类型转换运算符

有这么几行代码:

这是默认的shared_ptr中保存的是一个空指针。第二个输出结果为00000000我可以理解,shared_ptr重载了<<操作符,最终调用的是shared_ptr里面的_Px.get()。

第一个输出结果为false我就不理解了。虽然默认的shared_ptr中保存的是空指针,但是shared_ptr对象本身不为空,为什么行为跟空指针一样呢,if判断shared_ptr对象竟然是false,这背后肯定做了什么。

代码跳转到shared_ptr代码的定义,没有发现什么。只好反汇编一下if(p)的代码。反汇编显示调用的是std::shared_ptr<int>::operator bool。然后在代码这里再下一个断点,果然走到了这里。

QQ20150221105855

以前只看到重载函数调用符operator()()的用法,对于operator bool()却没有什么印象。然后翻书一看,原来这是类型转换运算符函数。if()会把表达式结果转换成一个bool值,从而会调用到对象的operator bool()方法。

类型转换运算符是类的一种特殊的成员函数,它负责将一个类类型的值转换成其他类型,一般形式如下:operator Type() const;
其中Type是表示某种类型。类型转换运算符可以面向任意类型(除了void之外)进行定义,只要该类型能作为函数的返回类型。因此不允许转成数组或者函数类型,但允许转换成指针或者引用类型。

类型转换运算符既没有显式的返回类型,也没有形参,而且必须定义成类的成员函数。它也不应该改变待转换对象的内容,因此,一般定义成const成员。

我们定义一个string_int的类,可以使string类型隐式转成int跟int类型做运算。

类型转换运算符虽然可以简化我们代码的使用,但是必须要避免过度使用它,因为隐式转换有时候会带来误导性。实践中类很少提供类型转换运算符,但是定义向bool的类型转换还是比较普遍的现象。

类型转换运算符有时候会造成意外的结果。

上面代码可以编译通过。这段代码试图将输出运算符作用于输入运算符。因为istream本身并没有定义<<,所以本来代码应该产生错误的。然后该代码能使用istream的bool类型转换运算符将cin转换成bool,而这个bool值接着会被提升成int并用作内置的左移运算符的左侧运算对象。

为了防止这样的异常情况的发生,c++11引入explicit显式的类型转换运算符。这样编译器不会将一个显式的类型转换运算符用于隐式类型转换。该规定有个例外:如果表达式被用作条件,则编译器会将显式的类型转换自动应用于它。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注