什么时候应该使用 static_cast、dynamic_cast、const_cast 和 reinterpret_
技术问答
391 人阅读
|
0 人回复
|
2023-09-11
|
正确的用途是什么:
; {3 X) k! U0 j: Q% i6 Hstatic_cast
/ l/ c4 B3 |" o2 }$ a5 q( H8 m( l/ Fdynamic_cast9 G5 Z+ T/ B {' p4 G! ?
const_cast
. ^# ^( W' d# k s* p; \reinterpret_cast
0 ^% Z, j* } gC型演员表(type)value/ ]& o0 M3 O% } U$ T, Y
函数式强制转换type(value)在特定情况下,如何决定使用哪个?
) Q. w2 F$ V5 p2 |; c% ^4 p+ I
7 c5 X' b$ L: L; {5 X: r* _) | 解决方案: % f1 F4 e2 _2 E/ c3 K7 }) [
static_cast这是你应该尝试使用的第一个演员表。它执行类型之间的隐藏转换(例如inttofloat或指向 指针void*)它还可以调用显式转换函数(或隐式转换函数)。在许多情况下,static_cast不需要明确的声明,但重要的是要注意T(something)语法等效于(T)something并且应该避免(稍后会详细介绍)。然而,AT(something,something_else)结构函数的调用是安全的。) v; v# k; J- ~3 G# j" t. m- `
static_cast也可以通过继承层结构进行转换。向上转换(向基类)是不必要的,但向下转换时,只要不通过virtual继承可以用于转换。但是,它不会被检查,而且会被检查static_cast不是对象类型的类型是未定义的行为。
: ?: r8 |( n1 B. \4 h' rconst_cast可用于删除或添加const变量;没有别的 C 演员可以删除(甚至没有)reinterpret_cast)。需要注意的是,只有当原始变量为时,才能修改以前的变量const值是未定义的。const如果你用它来取消对方const引用未声明的内容const,它是安全的。例如,它对基于 重载成员函数非常有用const。也可用于添加const例如,在一个对象中调用成员函数的重载。
0 X6 n3 R& w/ Q# A% G* |9 c, _. Dconst_cast也同样适用于volatile,尽管这种情况并不常见。
& s/ `& b, ^5 \% ] z: Vdynamic_cast专门用于处理多态性。您可以将指向任何多态类型的指针或引用转换为任何其他类型(多态类型至少有一个声明或继承的虚拟函数)。您不仅可以将其用于向下投射 - 你也可以向侧面投射,甚至向上投射另一条链。dynamic_cast在可能的情况下找到所需的对象并返回它。如果没有,它会nullptr返回指针情况下返回,或在引用的情况下抛出std::bad_cast。7 r* Q- K& R& J6 Q# N
dynamic_cast但也有一些限制。virtual如果继承层结构中有许多相同类型的对象(所谓的可怕的钻石),而你不使用继承,它就不起作用。它只能通过公共继承——它总是不能通过protected或private继承。然而,这很少成为问题,因为这种继承形式很少见。2 e+ N$ G; J: W% l2 l |
reinterpret_cast*它是最危险的演员表,应该非常小心使用。它直接将一种类型转换为另一种类型——例如,将值从一个指针转换为另一个指针,或将指针存储在 中int,或者其他烦人的事情。在很大程度上,你得到的唯一保证reinterpret_cast是的,通常,如果你将结果转换为原始类型,你将获得相同的值(但如果中间类型小于原始类型,则不会)。*也有许多reinterpret_cast**不能做的转换。它主要用于特别奇怪的转换和位操作,如将原始数据流转换为实际数据,或将数据存储在指向对齐数据的指针的低位。
2 V6 @% A3 C0 ~/ gC 风格转换和函数风格单独使用转换(type)objector进行转换type(object),而且在功能上是等价的。它们被定义为以下成功的第一个:
) a! k; V# v6 r" j" N' Rconst_cast1 d% q# D& `* u: G
static_cast(虽然忽略了访问限制)
$ V; O8 P- L W# Nstatic_cast(见上文),然后const_cast
3 l9 O3 e" z r9 _reinterpret_cast) }. R2 q0 W# y+ x
reinterpret_cast,然后const_cast因此,在某些情况下,它可以用作其他类型转换的替代品,但它可以演变成 a reinterpret_cast,因此,除非你确定,否则可能非常危险,需要显式转换时应首选后者static_cast会成功或reinterpret_cast会失败.即便如此,也要考虑更长、更清晰的选项。: E$ s1 V* N' Z$ T8 T3 L% N4 I4 n
C 风格的强制转换转换a 也会忽略访问控制static_cast,这意味着它们可以执行其他不能执行强制转换的操作。然而,这主要是一种杂物。在我看来,这只是为了避免 C 风格转换的另一个原因。 |
|
|
|
|
|