小编典典

为什么使用 static_cast(x) 而不是 (int)x?

all

我听说该static_cast函数应该优先于 C 样式或简单的函数样式转换。这是真的?为什么?


阅读 117

收藏
2022-03-02

共1个答案

小编典典

主要原因是经典的 C 类型转换不区分我们所说static_cast<>()的 ,
reinterpret_cast<>(),const_cast<>()dynamic_cast<>(). 这四件事是完全不同的。

Astatic_cast<>()通常是安全的。语言中有一个有效的转换,或者一个适当的构造函数使它成为可能。唯一有点冒险的时候是当你放弃继承的类时;您必须确保该对象实际上是您声称的后代,通过语言外部的方式(如对象中的标志)。dynamic_cast<>()只要检查结果(指针)或考虑可能的异常(参考),A就是安全的。

另一方面,A reinterpret_cast<>()(或 a )总是危险的。const_cast<>()你告诉编译器:“相信我:我知道这看起来不像
a 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 风格的强制转换更危险,而且很难找到它们以确保它们是正确的。

2022-03-02