Both static_cast
and reinterpret_cast
seem to work fine for casting void*
to another pointer type. Is there a good reason to favor one over the other?
8 回答
使用static_cast
:它是准确描述此处进行的转换的最窄类型。
有一种误解认为 usingreinterpret_cast
会更好,因为它意味着“完全忽略类型安全,只是从 A 转换为 B”。
但是,这实际上并没有描述reinterpret_cast
. 相反,reinterpret_cast
它具有多种含义,因为所有含义都认为“执行的映射reinterpret_cast
是实现定义的”。[5.2.10.3]
void*
但是在从映射到映射的特殊情况下,T*
标准完全定义了它;即,将类型分配给无类型指针而不更改其地址。
这是一个偏爱的理由static_cast
。
此外,可以说更重要的是,每次使用都reinterpret_cast
非常危险,因为它将任何东西都转换为其他任何东西(对于指针),同时static_cast
限制性更强,从而提供了更好的保护级别。这已经使我免于意外尝试将一种指针类型强制转换为另一种的错误。
static_cast
更适合将 a 转换为其他void*
类型的指针。
static_cast
当两种类型之间存在自然、直观的转换且不一定保证在运行时工作时,它是首选。例如,您可以使用static_cast
将基类指针转换为派生类指针,这种转换在某些情况下是有意义的,但直到运行时才能验证。同样,您可以使用将 astatic_cast
转换int
为 a char
,这是定义明确的,但在执行时可能会导致精度损失。
reinterpret_cast
另一方面,它是一个铸造操作员,旨在进行根本不安全或不可移植的转换。例如,您可以使用reinterpret_cast
将 a 转换为void *
,如果您的系统恰好有≤ int
,它将正常工作。您还可以使用将 a 转换为 a或反之亦然,这是特定于平台的,因为不保证s 和s 的特定表示彼此有任何共同之处。sizeof (void*)
sizeof (int)
reinterpret_cast
float*
int*
float
int
简而言之,如果您发现自己在进行转换,其中强制转换在逻辑上是有意义的,但在运行时不一定会成功,请避免reinterpret_cast
. static_cast
如果您预先知道强制转换将在运行时工作,并且与编译器通信,这是一个不错的选择“我知道这可能不起作用,但至少它是有道理的,我有理由相信它会正确在运行时做正确的事。” 然后编译器可以检查转换是否在相关类型之间,如果不是这种情况,则报告编译时错误。使用reinterpret_cast
指针转换完全绕过编译时安全检查。
在某些情况下,您可能希望使用 adynamic_cast
而不是 a static_cast
,但这些主要涉及类层次结构中的强制转换,并且(很少)直接关注void*
。
至于规范首选哪一个,两者都没有被过度提及为“正确的使用”(或者至少,我不记得其中一个是这样提到的。)但是,我认为规范希望你使用static_cast
结束reinterpret_cast
。例如,当使用 C 风格转换时,如
A* ptr = (A*) myVoidPointer;
尝试的强制转换运算符的顺序总是尝试在 astatic_cast
之前使用 a reinterpret_cast
,这是您想要的行为,因为reinterpret_cast
不能保证是可移植的。
这是一个棘手的问题。一方面,Konrad 对reinterpret_cast的规范定义提出了一个很好的观点,尽管在实践中它可能会做同样的事情。另一方面,如果您在指针类型之间进行转换(例如,在通过 char* 在内存中进行索引时相当常见),static_cast将产生编译器错误,并且无论如何您都将被迫使用reinterpret_cast 。
在实践中,我使用reinterpret_cast因为它更能描述转换操作的意图。您当然可以为不同的运算符指定仅重新解释指针的情况(保证返回相同的地址),但标准中没有。
您可能通过void*
隐式转换获得了它,因此您应该使用static_cast
它,因为它最接近隐式转换。
用于static_cast
此。只有在极少数情况下没有其他方法时才使用reinterpret_cast
。
使用和使用void*
的转换是相同的。请参阅链接中的答案。但通常是首选,因为它更窄并且通常(但不是在这种特定情况下)更安全的转换。static_cast
reinterpret_cast
static_cast
我建议始终使用最弱的演员阵容。
reinterpret_cast
可用于将指针强制转换为float
. 铸件的结构破坏越多,使用它需要的注意力就越多。
在 的情况下char*
,我会使用 c 风格的演员表,直到我们有一些reinterpret_pointer_cast
,因为它更弱,没有其他东西是足够的。
reinterpret_cast
将强制转换void*
为目标数据类型。它不能保证任何安全性,并且您的程序可能会崩溃,因为底层对象可能是任何东西。
例如,您可以对一个myclass*
to 进行类型转换void*
,然后使用reinterpret_cast
将其转换为yourclass*
可能具有完全不同的布局。
所以它更好,推荐使用static_cast