我听说该static_cast函数应该优先于 C 样式或简单的函数样式转换。这是真的?为什么?
static_cast
主要原因是经典的 C 类型转换不区分我们所说static_cast<>()的 , reinterpret_cast<>(),const_cast<>()和dynamic_cast<>(). 这四件事是完全不同的。
static_cast<>()
reinterpret_cast<>()
const_cast<>()
dynamic_cast<>()
Astatic_cast<>()通常是安全的。语言中有一个有效的转换,或者一个适当的构造函数使它成为可能。唯一有点冒险的时候是当你放弃继承的类时;您必须确保该对象实际上是您声称的后代,通过语言外部的方式(如对象中的标志)。dynamic_cast<>()只要检查结果(指针)或考虑可能的异常(参考),A就是安全的。
另一方面,A reinterpret_cast<>()(或 a )总是危险的。const_cast<>()你告诉编译器:“相信我:我知道这看起来不像 a foo(这看起来好像它不是可变的),但它是”。
foo
第一个问题是,如果不查看大量分散的代码片段并了解所有规则,几乎不可能判断出哪个会出现在 C 风格的转换中。
让我们假设这些:
class CDerivedClass : public CMyBase {...}; class CMyOtherStuff {...} ; CMyBase *pSomething; // filled somewhere
现在,这两个编译方式相同:
CDerivedClass *pMyObject; pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<> // Safe; as long as we checked // but harder to read
但是,让我们看看这个几乎相同的代码:
CMyOtherStuff *pOther; pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert pOther = (CMyOtherStuff*)(pSomething); // No compiler error. // Same as reinterpret_cast<> // and it's wrong!!!
如您所见,如果不了解所涉及的所有类,就没有简单的方法来区分这两种情况。
第二个问题是 C 风格的演员阵容太难定位了。在复杂的表达式中,很难看到 C 风格的强制转换。如果没有成熟的 C++ 编译器前端,几乎不可能编写需要定位 C 风格转换的自动化工具(例如搜索工具)。另一方面,很容易搜索“static_cast<”或“reinterpret_cast<”。
pOther = reinterpret_cast<CMyOtherStuff*>(pSomething); // No compiler error. // but the presence of a reinterpret_cast<> is // like a Siren with Red Flashing Lights in your code. // The mere typing of it should cause you to feel VERY uncomfortable.
这意味着,不仅 C 风格的强制转换更危险,而且很难找到它们以确保它们是正确的。