static_cast
static_cast
是您应该尝试使用的第一个演员表。它执行诸如类型之间的隐式转换之类的操作(例如int
to float
,或指向void*
),并且它还可以调用显式转换函数(或隐式转换函数)。在许多情况下,明确说明static_cast
不是必需的,但重要的是要注意T(something)
语法相当于(T)something
并且应该避免(稍后会详细介绍)。 AT(something, something_else)
然而,它是安全的,并且保证调用构造函数。
static_cast
也可以通过继承层次结构进行转换。当向上投射(朝向基类)时,这是不必要的,但是当向下投射时,只要它不穿透就可以使用virtual
遗产。但是,它不进行检查,并且这是未定义的行为static_cast
沿着层次结构下降到实际上不是对象类型的类型。
const_cast
const_cast
可用于删除或添加const
到一个变量;没有其他 C++ 强制转换能够删除它(甚至不能reinterpret_cast
)。需要注意的是,修改之前的const
仅当原始变量是时,值才是未定义的const
;如果你用它来采取const
关闭对未声明的内容的引用const
,这是安全的。当基于以下内容重载成员函数时,这非常有用const
, 例如。也可以用来添加const
到一个对象,例如调用成员函数重载。
const_cast
也同样适用于volatile
,尽管这种情况不太常见。
dynamic_cast
dynamic_cast
专门用于处理多态性。您可以将对任何多态类型的指针或引用强制转换为任何其他类类型(多态类型至少有一个声明或继承的虚函数)。您不仅可以使用它向下施法,还可以向侧面施法,甚至可以向上施法另一条链。这dynamic_cast
将寻找所需的对象并在可能的情况下将其返回。如果不能的话就会返回nullptr
在指针的情况下,或者抛出std::bad_cast
在有参考的情况下。
dynamic_cast
但有一些限制。如果继承层次结构中有多个相同类型的对象(所谓的“可怕的钻石”)并且您没有使用它,则它不起作用virtual
遗产。它也只能通过公共继承——它总是无法通过protected
or private
遗产。然而,这很少是一个问题,因为这种形式的继承很少见。
reinterpret_cast
reinterpret_cast
是最危险的演员,应该非常谨慎地使用。它将一种类型直接转换为另一种类型——例如将值从一个指针转换为另一个指针,或者将指针存储在int
,或各种其他令人讨厌的事情。很大程度上,这是您获得的唯一保证reinterpret_cast
通常情况下,如果将结果转换回原始类型,您将得到完全相同的值(但是not如果中间类型小于原始类型)。有很多转换,reinterpret_cast
也做不到。它主要用于特别奇怪的转换和位操作,例如将原始数据流转换为实际数据,或者将数据存储在指向对齐数据的指针的低位中。
C 风格转换和函数风格转换
C 风格的强制转换和函数风格的强制转换是使用(type)object
or type(object)
,分别,并且在功能上是等效的。它们被定义为以下第一个成功的:
const_cast
-
static_cast
(尽管忽略访问限制)
-
static_cast
(见上文),那么const_cast
reinterpret_cast
-
reinterpret_cast
, then const_cast
因此,在某些情况下,它可以用作其他演员的替代品,但由于能够转变为reinterpret_cast
,当需要显式转换时,应该首选后者,除非您确定static_cast
会成功或reinterpret_cast
将失败。即便如此,请考虑更长、更明确的选项。
C 风格的强制转换在执行时也会忽略访问控制static_cast
,这意味着他们有能力执行其他演员无法执行的操作。不过,这主要是一个拼凑,在我看来,这只是避免 C 风格强制转换的另一个原因。