static_cast和reinterpret_cast似乎都可以将void *强制转换为另一种指针类型。是否有充分的理由偏爱一个?
static_cast和reinterpret_cast似乎都可以将void *强制转换为另一种指针类型。是否有充分的理由偏爱一个?
Answers:
用途static_cast
:这是最狭窄的演员表,准确描述了在此进行的转换。
有一个误解,认为使用reinterpret_cast
会是更好的匹配,因为这意味着“完全忽略类型安全性,而只是从A转换为B”。
但是,这实际上并未描述的效果reinterpret_cast
。而是reinterpret_cast
具有多种含义,所有这些含义都意味着“由reinterpret_cast
执行的映射是实现定义的”。[5.2.10.3]
但是在特定情况下,从void*
到强制转换T*
的映射完全由标准定义。也就是说,在不更改其地址的情况下将类型分配给无类型指针。
这是喜欢的理由static_cast
。
另外,而且可能更重要的是,每次使用reinterpret_cast
都是彻头彻尾的危险,因为它实际上将任何内容转换为其他任何内容(对于指针),而static_cast
限制更严格,因此提供了更好的保护级别。这已经使我免于错误,因为我不小心尝试将一种指针类型转换为另一种类型。
这是一个棘手的问题。一方面,尽管在实践中Konrad 可能做同样的事情,但他对reinterpret_cast的规范定义提出了很好的观点。另一方面,如果要在指针类型之间进行转换(例如,通过char *在内存中建立索引,这是很常见的情况), static_cast将生成编译器错误,并且无论如何您都将被迫使用reinterpret_cast。
在实践中,我使用reinterpret_cast,因为它更能说明强制转换操作的意图。您当然可以让其他运算符指定只重新解释指针(以保证返回相同的地址),但标准中没有这样的情况。
reinterpret_cast
!
我建议始终使用最弱的演员表。
reinterpret_cast
可以用于将指针转换为float
。演员表破坏结构越多,使用它所需要的关注就越多。
在的情况下char*
,我将使用c样式强制转换,直到有了reinterpret_pointer_cast
,因为它比较弱,没有其他足够的了。
float f = *reinterpret_cast<const float*>(&p);
float
,这是错误的。该表达式强制转换void **
为const float *
,然后使用解引用操作(不是强制转换)转换const float *
为float
。
我个人的偏爱基于这样的代码素养:
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在中间件,应用程序环境中似乎更合适,而重新解释类型转换似乎更像您在较低层库IMHO中看到的东西。