首先,这不是Why do we have reinterpret_cast in C++ when two chained static_cast can do it's job?的副本。
我知道我们甚至不能使用两个链式static_cast
来实现这一点的情况,reinterpret_cast
的作用。但是,在任何情况下我都应该选择两个链式static_cast
而不是一个简单且更具可读性的reinterpret_cast
吗?
答案 0 :(得分:9)
reinterpret_cast
应该是一个巨大的闪烁符号,说这看起来很疯狂,但我知道我在做什么。不要只是出于懒惰而使用它。
reinterpret_cast
表示“将这些位视为......”链式静态强制转换不相同,因为它们可能会根据继承点格式修改其目标。
struct A {
int x;
};
struct B {
int y;
};
struct C : A, B {
int z;
};
C c;
A * a = &c;
int main () {
assert (reinterpret_cast <B *> (a) != static_cast <B *> (static_cast <C *> (a)));
}
如果您不是100%确定a
指向b
,请使用dynamic_cast
来搜索上述解决方案(尽管有运行时费用)。请记住,这可能会返回NULL或失败。
我正在考虑我实际使用reinterpret_cast
的时间,实际上只有两个:
const char *
来遍历它时if(*reinterpret_cast<uint32_t*>(array_of_4_bytes_A) < *reinterpret_cast<uint32_t*>(array_of_4_bytes_B)
或其他一些人。像这样的行邀请审查和要求评论。否则,如果你的A*
真的是B*
,那么你可能想要一个联盟。
答案 1 :(得分:5)
我希望任何时候都能看到reinterpret_cast <TargetType> (pointer_of_some_other_type)
而不是static_cast <TargetType> (static_cast <void*> (pointer_of_some_other_type))
或static_cast <TargetType> ((void*) (pointer_of_some_other_type))
。通过void *的演员链只是一种偷偷摸摸的,不道德的方式,以避免使用可怕的reinterpret_cast。
许多项目禁止使用reinterpret_cast,除非获得豁免;编写代码的人需要证明使用演员表。 IMO,静态演员链比
<强>附录强>
以这种方式看待它。案例1,你使用reinterpret_cast,你通过所有的项目箍来证明它的使用,项目经理给予豁免。几个月后,您可以通过使用dynamic_cast来查看错误。你有一张免于监狱的卡。这是项目经理的屁股,可以为您提供该卡。
案例2,你使用偷偷摸摸的,卑鄙的静态演员链并且代码偷偷通过同行评审毫发无损。几个月后,一个错误可以追溯到你使用卑鄙的技术。你的项目经理可能因为没有抓住这种肮脏而有点麻烦,但这是你的屁股。你没有那个出狱的免费卡。你没有通过Go。你直接去失业线。
答案 2 :(得分:2)
始终使用重新解释演员作为最后的手段 - 它不做任何检查! - 所以,如果你可以将两个,三个或十个语句链接在一起,对操作进行某种验证,那么你就获得了一些有价值的东西。
答案 3 :(得分:2)
因为,情景列表可能会很长,我用简单的话来说:
如果链接static_cast<>
没有给出编译错误,则应该避免reinterpret_cast<>
。
答案 4 :(得分:1)
在交叉投射指针的情况下你应该not use reinterpret_cast
- 而是使用隐式转换为void*
,然后使用static_cast
。
答案 5 :(得分:0)
因为从理论上讲,他们可以做一些不同的事情(尽管很难想象这样的情况)。更重要的是,它们向读者发送不同的信号,并向编译器讲述不同的故事(这可能会影响优化)。从逻辑上讲,我会说使用链接static_cast
到void*
来处理来自/来自字符类型的情况(例如,转储原始内存的图像),以及其他明确定义和可移植的情况,{ {1}}当您进行真正的低级别硬件相关工作时:例如,通过将其地址转换为reinterpret_cast
来提取float
的指数字段,并进行位屏蔽。