【More Effective C++】Item 2
Item 2:最好使用C++提供的转型操作符
对于很多从C转行从事C++的开发人员来说,都习惯使用C语言提供的强制类型转换,即使用“(类型)”这种方式,但是这种方式在C++中却是非常不好的习惯:
原因一:不管是开发人员还是开发工具,都不能很好的察觉该转型符;
原因二:不安全,C风格的转型符可以实现任何类型之间的转换,且其不能提示是否转型成功;
原因三:C++中,为了弥补这些缺陷,设计了新的转型符,安全性更高,且更容易被开发工具察觉。
第一个类型:static_cast转型符
用法:static_cast<类型>(表达式);
说明:其基本拥有了与C旧式转型相同的威力和意义,以及相同的限制,但是它不能将一个struct转换了int,或者将一个double转换为pointer等等,这些都是C转型符所不能完成的任务,因此它更安全;
注意:其不能用于去除变量的常属性(那是const_cast转型符的用途),一般也不用于继承体系中(那是dynamic_cast转型符的用途),也不用于对函数指针进行强制转型(那是reinterpret_cast转型符的用途)。
第二个类型:const_cast转型符
用法:const_cast<类型>(表达式);
说明:其只用于去除变量的常属性(constness);
注意:如果将其用于其它用途,那么转型动作会被拒绝。
第三个类型:dynamic_cast转型符
用法:dynamic_cast<类型>(表达式);
说明:其只用于继承体系中“安全的向下转型或跨系转型”,并得知转型是否成功,如果失败,将返回一个null指针(当转型对象是指针)或者一个exception(当转型对象是引用);
注意:它无法应用在缺乏虚函数的类型身上,也不能改变变量的常量性。
第四个类型:reinterpret_cast转型符
用法:reinterpret_cast<类型>(表达式);
说明:其用于转换“函数指针”类型;但是他不具移植性,应尽量少用;
注意:函数指针的转型动作,并不具有移植性(C++不保证所有的函数指针都能以此方式重新呈现),某些情况下这样的转型可能还会导致不正确的结果。因此你应该尽量少用,除非你已经走投无路了。
如果你的编译器尚未支持这些新型转型符,那么可以使用传统的方法来取代它们:
1、#define static_cast(TYPE,EXPR) ((TYPE)(EXPR))
2、#define const_cast(TYPE,EXPR) ((TYPE)(EXPR))
3、#define dynamic_cast(TYPE,EXPR) ((TYPE)(EXPR))
4、#define reinterpret_cast(TYPE,EXPR) ((TYPE)(EXPR))