C ++什么时候我们更喜欢在reinterpret_cast上使用两个链式的static_cast

时间:2011-07-06 09:44:01

标签: c++ casting reinterpret-cast static-cast

首先,这不是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吗?

6 个答案:

答案 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,静态演员链比更差(更糟糕!)。该链具有相同的效果,与reinterpret_cast具有相同的问题,但链不具有易于使用grep查找的好处。

<强>附录
以这种方式看待它。案例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_castvoid*来处理来自/来自字符类型的情况(例如,转储原始内存的图像),以及其他明确定义和可移植的情况,{ {1}}当您进行真正的低级别硬件相关工作时:例如,通过将其地址转换为reinterpret_cast来提取float的指数字段,并进行位屏蔽。