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

0xb*_*00d 8 c++ casting static-cast reinterpret-cast

首先,这不是重复的为什么当两个链接的static_cast可以完成它的工作时,我们在C++中有reinterpret_cast?.

我知道我们甚至不能使用两个连锁static_cast来实现这reinterpret_cast一点的情况.但是,在任何情况下我都应该选择两个链接static_cast而不是简单且更具可读性的情况reinterpret_cast吗?

spr*_*aff 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)));
}
Run Code Online (Sandbox Code Playgroud)

如果你不是100%肯定a指向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*那么你可能想要一个联盟.

  • 请注意,通过`void*`进行两次静态强制转换的代码*和`reinterpret_cast`一样疯狂*,但是你不再拥有巨大的闪烁符号.如果你认为这很疯狂,你应该留下疯狂警告.如果你认为它不是疯了,你应该删除疯狂警告. (2认同)
  • 疯狂.那个大闪烁的疯狂警告很重要.不要隐藏它. (2认同)

Dav*_*men 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 更糟糕(更糟糕!).该链具有与reinterpret_cast相同的效果,同样的问题,但链不具有易于使用grep查找的好处.

附录
以这种方式看待它.案例1,你使用reinterpret_cast,你通过所有的项目箍来证明它的使用,项目经理给予豁免.几个月后,您可以通过使用dynamic_cast来查看错误.你有一张免于监狱的卡.这是项目经理的屁股,可以为您提供该卡.

案例2,你使用偷偷摸摸,卑鄙的静态演员链和代码偷偷通过同行评审毫发无损.几个月后,一个错误可以追溯到你使用卑鄙的技术.你的项目经理可能因为没有抓住这种肮脏而有点麻烦,但这是你的屁股.你没有那个出狱的免费卡.你没有通过Go.你直接去失业线.


sha*_*oth 1

您不应该在交叉转换指针的情况下使用reinterpret_castvoid*- 而是使用隐式转换为, then static_cast