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

新手上路,请多包涵

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

原文由 Tommy Herbert 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 855
2 个回答

The main reason is that classic C casts make no distinction between what we call static_cast<>() , reinterpret_cast<>() , const_cast<>() , and dynamic_cast<>() .这四件事是完全不同的。

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

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

原文由 Euro Micelli 发布,翻译遵循 CC BY-SA 4.0 许可协议

简而言之

  1. static_cast<>() 给你一个编译时检查能力,C-Style cast 没有。
  2. static_cast<>() 可以在 C++ 源代码中的任何位置轻松发现;相比之下,C_Style 演员更难发现。
  3. 使用 C++ 强制转换可以更好地传达意图。

更多解释

静态转换执行 兼容类型 之间的转换。它类似于 C 风格的演员表,但更具限制性。例如,C 风格的转换将允许一个整数指针指向一个字符。

 char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

由于这会导致 4 字节指针指向已分配内存的 1 字节,因此写入该指针将导致运行时错误或将覆盖一些相邻的内存。

 *p = 5; // run-time error: stack corruption

与 C 风格的转换相比,静态转换将允许编译器检查指针和指针数据类型是否兼容,这允许程序员在编译期间捕获这种不正确的指针分配。

 int *q = static_cast<int*>(&c); // compile-time error

阅读更多:

static_cast<> 和 C 风格转换有什么区别

常规演员与 static_cast 与 dynamic_cast

原文由 Hossein 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题