static_cast和reinterpret_cast似乎都可以很好地将void *转换为另一个指针类型。是否有充分理由支持其他人?
答案 0 :(得分:121)
使用static_cast
:它是最精确的演员,它准确描述了此处进行的转换。
有一种误解,认为使用reinterpret_cast
会更好地匹配,因为它意味着“完全忽略类型安全,只是从A转换为B”。
但是,这实际上并没有描述reinterpret_cast
的效果。相反,reinterpret_cast
具有许多含义,因为所有这些含义都表明“由reinterpret_cast
执行的映射是实现定义的。”[5.2.10.3]
但是在从void*
转换为T*
的特定情况下,映射完全由标准定义;即,将类型分配给无类型指针而不改变其地址。
这是首选static_cast
的理由。
此外,可以说更重要的是,reinterpret_cast
的每次使用都是彻头彻尾的危险,因为它将任何东西转换为其他任何东西(用于指针),而static_cast
则更具限制性,因此提供更好的保护。这已经让我免于我偶然试图将一种指针类型强制转换为另一种指针类型的错误。
答案 1 :(得分:7)
这是一个棘手的问题。一方面,Konrad对 reinterpret_cast 的规范定义提出了一个很好的观点,尽管在实践中它可能做同样的事情。另一方面,如果你在指针类型之间进行转换(例如,当通过char *在内存中索引时相当常见), static_cast 将生成编译器错误并且你将被强制无论如何要使用 reinterpret_cast 。
在实践中,我使用 reinterpret_cast ,因为它更能描述强制转换操作的意图。您当然可以为不同的运算符设置一个仅指定指针重新解释的情况(保证返回相同的地址),但标准中没有一个。
答案 2 :(得分:1)
我建议总是使用最弱的演员。
reinterpret_cast
可用于投射指向float
的指针。演员阵容的结构越多,使用它的注意力就越多。
如果是char*
,我会使用c风格的演员,直到我们有一些reinterpret_pointer_cast
,因为它更弱,没有其他的就足够了。
答案 3 :(得分:1)
使用 void*
和使用 static_cast
来回转换 reinterpret_cast
是相同的。请参阅 the link 处的答案。但通常首选 static_cast
,因为它更窄,并且通常(但不是在这种特定情况下)转换更安全。
答案 4 :(得分:-6)
我个人的偏好是基于这样的代码识字:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
或
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
他们最终都做了同样的事情,但static_cast似乎更适合中间件,app环境,而重新解释演员看起来更像是你在较低级别的图书馆IMHO中看到的东西。