在将void *强制转换为任何值时,应该使用static_cast还是reinterpret_cast


Answers:


148

用途static_cast:这是最狭窄的演员表,准确描述了在此进行的转换。

有一个误解,认为使用reinterpret_cast会是更好的匹配,因为这意味着“完全忽略类型安全性,而只是从A转换为B”。

但是,这实际上并未描述的效果reinterpret_cast。而是reinterpret_cast具有多种含义,所有这些含义都意味着“由reinterpret_cast执行的映射是实现定义的”。[5.2.10.3]

但是在特定情况下,从void*到强制转换T*的映射完全由标准定义。也就是说,在不更改其地址的情况下将类型分配给无类型指针。

这是喜欢的理由static_cast

另外,而且可能更重要的是,每次使用reinterpret_cast都是彻头彻尾的危险,因为它实际上将任何内容转换为其他任何内容(对于指针),而static_cast限制更严格,因此提供了更好的保护级别。这已经使我免于错误,因为我不小心尝试将一种指针类型转换为另一种类型。


8

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

在实践中,我使用reinterpret_cast,因为它更能说明强制转换操作的意图。您当然可以让其他运算符指定只重新解释指针(以保证返回相同的地址),但标准中没有这样的情况。


6
不同的运算符只指定指针重新解释(保证返回相同的地址) ”拥抱吗?那个运算符 reinterpret_cast
curiousguy 2011年

2
@curiousguy根据标准不正确。reinterpret_cast不保证使用相同的地址。仅当您将reinterpret_cast从一种类型重新转换为另一种类型,然后再次返回时,您才能获得与开始时相同的地址。
ClydeTheGhost

0

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

reinterpret_cast可以用于将指针转换为float。演员表破坏结构越多,使用它所需要的关注就越多。

在的情况下char*,我将使用c样式强制转换,直到有了reinterpret_pointer_cast,因为它比较弱,没有其他足够的了。


2
reinterpret_cast可用于将指针转换为浮点数。 ”当然不能!
curiousguy 2011年

3
可能float f = *reinterpret_cast<const float*>(&p);
Ben Voigt

2
@BenVoigt在指针之间进行转换;其中之一碰巧是一个浮动指针。
nodakai

5
@BenVoigt的“整个表达式”不是强制转换。该表达式包含应用于演员表的取消引用。您声称可以将指针转换为float,这是错误的。该表达式强制转换void **const float *,然后使用解引用操作(不是强制转换)转换const float *float
MM

2
@BenVoigt,您提供该代码是为了回应某人询问“我如何进行转换...”,然后当有人说该代码在指针之间进行转换时(确实如此),您说“不”
MM

-7

我个人的偏爱基于这样的代码素养:

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中看到的东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.