类型转换中如何适当使用static_cast/const_cast/dynamic_cast/reinterpret_cast[译]

Published: 23 Apr 2013 Category: 编程

原文转自:http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used

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继承,无法转换protectedprivate继承。

(注: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转换应该避免。

?

?