在什么情况下,应该使用双链式static_cast而不是reinterpret_cast ?
C++ When should we prefer to use a two chained static_cast over reinterpret_cast
首先,这不是c++中为什么两个链接的static_cast可以完成它的工作时,我们有reinterpret_cast的副本。
我知道在某些情况下,我们甚至不能使用两个链static_cast
来实现reinterpret_cast
的作用。但是,是否有任何情况下,我应该更喜欢两个链接的static_cast
,而不是一个简单的和更可读的reinterpret_cast
?
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*
,那么你可能需要一个并集
我宁愿看到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,除非获得豁免;编写代码的人需要证明强制转换的使用是正确的。在我看来,静态强制转换链比reinterpret_cast更差(差得多!)该链具有与reinterpret_cast相同的效果和相同的问题,但是该链不具有易于使用grep查找的优点。
附录
这样看。情况1,你使用reinterpret_cast,你通过所有的项目流程来证明它的使用是合理的,项目经理同意放弃。几个月后,一个错误被追踪到您使用了dynamic_cast。你有一张免坐牢卡。给你那张卡片是项目经理的责任。
用例2,您使用了偷偷摸摸的静态类型转换链,代码会安然无恙地通过同行评审。几个月后,一个错误被追查到你使用了卑鄙的技术。你的项目经理可能会因为没有发现这些肮脏的东西而遇到一点麻烦,但这是你的屁股。你没有那张免坐牢卡。你没有通过围棋。你直接去找失业救济
总是把重新解释强制转换作为最后的手段——它不做任何检查!-所以如果你能把两个,三个或十个语句链接在一起,对操作进行某种形式的验证,那么你就获得了一些有价值的东西。
由于场景列表可能很长,所以我用简单的话来表示:
如果链接的static_cast<>
不会产生编译错误,那么应该避免使用reinterpret_cast<>
。
你不应该在交叉转换指针的情况下使用reinterpret_cast
-而是使用隐式转换到void*
,然后static_cast
。
因为从理论上讲,它们可以做一些不同的事情(尽管很难想象这种情况)。更重要的是,它们向读者发送不同的信号,并向编译器讲述不同的故事(这可能会影响优化)。从逻辑上讲,我会说使用链式static_cast
到void*
的情况下,从一个字符类型(例如转储原始内存的图像),和其他情况下,定义良好,可移植,和reinterpret_cast
当你做真正的低层次,硬件依赖的工作:提取float
的指数字段通过将其地址转换为unsigned int*
,和位掩码,例如。
- 如何理解C++标准N3337中的expr.const.cast子句8
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- C++Cast运算符过载
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- 收到错误"invalid use of non-static data member 'stu::n' "
- LNK1104:无法打开libpjproject-i386-Win32-vc14-Debug-Static.lib
- 我应该在 C++ 中何时/为什么使用 STATIC?
- 在VS2019项目中集成ImageMagick:x64-windows-static library
- 如何处理Boost Spirit X3导致Visual Studio 2019 "static initialization order fiasco"?
- "static char __ = []() -> char"的含义
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- 无法在 DLL 中链接 SDL2-static.lib
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- 错误:"cast"未命名类型void setCastDescription(std::string
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- C++线程"Call to non-static member function without an object argument"
- 出现这种错误的原因是什么"invalid use of non-static data member "
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- static是如何使用ClassA::m_variable处理所有类对象的
- 在[expr.static.cast]/4中,术语"一个可行函数"指的是什么