231

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?

4

8 回答 8

184

使用static_cast:它是准确描述此处进行的转换的最窄类型。

有一种误解认为 usingreinterpret_cast会更好,因为它意味着“完全忽略类型安全,只是从 A 转换为 B”。

但是,这实际上并没有描述reinterpret_cast. 相反,reinterpret_cast它具有多种含义,因为所有含义都认为“执行的映射reinterpret_cast是实现定义的”。[5.2.10.3]

void*但是在从映射到映射的特殊情况下,T*标准完全定义了它;即,将类型分配给无类型指针而不更改其地址。

这是一个偏爱的理由static_cast

此外,可以说更重要的是,每次使用都reinterpret_cast非常危险,因为它将任何东西都转换为其他任何东西(对于指针),同时static_cast限制性更强,从而提供了更好的保护级别。这已经使我免于意外尝试将一种指针类型强制转换为另一种的错误。

于 2008-11-21T22:58:16.670 回答
61

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_castfloat*int*floatint

简而言之,如果您发现自己在进行转换,其中强制转换在逻辑上是有意义的,但在运行时不一定会成功,请避免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不能保证是可移植的。

于 2011-02-16T07:28:25.123 回答
12

这是一个棘手的问题。一方面,Konrad 对reinterpret_cast的规范定义提出了一个很好的观点,尽管在实践中它可能会做同样的事情。另一方面,如果您在指针类型之间进行转换(例如,在通过 char* 在内存中进行索引时相当常见),static_cast将产生编译器错误,并且无论如何您都将被迫使用reinterpret_cast 。

在实践中,我使用reinterpret_cast因为它更能描述转换操作的意图。您当然可以为不同的运算符指定仅重新解释指针的情况(保证返回相同的地址),但标准中没有。

于 2008-11-21T23:46:24.280 回答
3

您可能通过void*隐式转换获得了它,因此您应该使用static_cast它,因为它最接近隐式转换。

于 2011-02-16T07:27:46.543 回答
1

用于static_cast此。只有在极少数情况下没有其他方法时才使用reinterpret_cast

于 2011-02-16T07:24:08.643 回答
1

使用和使用void*的转换是相同的。请参阅链接中的答案。但通常是首选,因为它更窄并且通常(但不是在这种特定情况下)更安全的转换。static_castreinterpret_caststatic_cast

于 2021-06-26T06:31:37.557 回答
0

我建议始终使用最弱的演员阵容。

reinterpret_cast可用于将指针强制转换为float. 铸件的结构破坏越多,使用它需要的注意力就越多。

在 的情况下char*,我会使用 c 风格的演员表,直到我们有一些reinterpret_pointer_cast,因为它更弱,没有其他东西是足够的。

于 2009-12-14T09:30:45.847 回答
-2

reinterpret_cast将强制转换void*为目标数据类型。它不能保证任何安全性,并且您的程序可能会崩溃,因为底层对象可能是任何东西。

例如,您可以对一个myclass*to 进行类型转换void*,然后使用reinterpret_cast将其转换为yourclass*可能具有完全不同的布局。

所以它更好,推荐使用static_cast

于 2011-02-16T07:28:10.920 回答