类型转换中如何适当使用static_cast/const_cast/dynamic_cast/reinterpret_cast[译]
dynamic_cast:用于指针/引用在继承树的转换。Run-time.
static_cast:通常的类型转换。
reinterpret_cast:位模式和极端情况使用。
const_cast:用于转换掉const。几乎没有人使用。
?
?
?
一般来说,static_cast用于常见的类型转换。它的作用好像是一个隐式转换,而且他可以调用显式或隐式的转换函数。再大部分场合,显示的声明static_cast是没有必要的,可以直接使用T(something)或者(T)something。
Static_cast可以用于类的层次结构中。当派生类转换为基类时是不需要使用的,当基类转换为派生类时,就可以使用static_cast,只要不牵扯到虚继承。它不会进行类型检查,但是如果使用static_cast将一个基类转换为这个对象根本不是的派生类,则是一个编译错误(undefined behavior)。
const_cast用于添加或删除变量的const修饰词,C++中没有其他的转换方式可以完成这个功能。这个功能貌似很少有人用到。
dynamic_cast几乎是专门用于处理多态问题,并且只能用于指针或者引用。可以使用它将一个指向多态类型的指针或引用转换为其他类型。(多态类型表示至少定义或者继承了一个虚函数)。它可以用于将基类转换为派生类,它如果是这个派生类,那么就会返回这个派生类对象或指针,否则返回指针NULL,如果是用于引用,则抛出异常std::bad_cast。
dynamic_cast有一些限制,首先它不能用于在继承树中同一个类型有不同类型的对象('dreaded diamond'),其次,他不能用于没有多态的环境。还有,它只能用于public继承,无法转换protected和private继承。
(注:It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond'),是不是说一个基类如果有两个派生类就无法使用dynamic_cast)
?
reinterpret_cast?是一个非常危险的转换方法,必须小心的使用它。它将一种类型直接转换为另一种类型,如转换一个指针成为其他类型的变量,或者用int变量存储一个指针,等等nasty的操作。在使用reinterpret_cast的过程中,唯一可以保证的就是可以将转换后的结果原封不动的转换回来。reinterpret_cast主要用于特别奇怪的转换以及位操作,例如将原始数据流转换为真实数据。
C-style转换使用(type)object或者type(object)。一个C风格的转换定义为下列第一个成功的转换:
- const_cast
- static_cast
- static_cast, then?const_cast
- reinterpret_cast
- reinterpret_cast, then?const_cast
因此在一些实例中它可以被用于其他转换的替代,但是由于它有可能变为reinterpret_cast,它是非常危险的。当需要显式转换时,一般使用C++风格,除非可以肯定static_cast可以成功或者reinterpret_cast会失败。
当C-style转换执行static_cast还会忽略掉访问控制,也就是说可以执行一些其他转换不可以做的操作。
综上所述,C-style转换应该避免。
?
?