static_cast <>和C样式转换有什么区别?

dic*_*oce 188 c++ casting static-cast

有什么理由喜欢static_cast<>超过C风格的演员吗?它们是等价的吗?他们有什么速度差异吗?

Gle*_*len 201

编译器检查C++样式转换.C样式强制转换不是,并且可能在运行时失败

此外,可以轻松搜索c ++样式转换,而搜索c样式转换则非常困难

另一个很大的好处是,4种不同的C++风格的演员阵容更清晰地表达了程序员的意图.

在编写C++时,我几乎总是使用C++而不是C风格.

  • 唯一可以在运行时失败的强制转换是`dynamic_cast`s. (58认同)
  • ˗1普通C cast`(int)something`不能失败 - 要么转换为int或编译错误. (18认同)
  • C++ reinterpret_cast <T>(U)在运行时可能会失败,就像C样式转换一样,并且它们与dynamic_cast <T>(U)失败的方式完全不同. (10认同)
  • @MinhTran对于C++风格,您可以通过源文件搜索关键字"cast".但是你想要用C风格的演员吗? (3认同)
  • 你能详细说明为什么C++演员比C演员更容易被搜索? (2认同)
  • @huangzonghao您可以搜索"(int)"或"int(".您需要知道的是您要搜索的类型,无论如何都应包括在内以过滤掉结果.但说实话,我不知道知道为什么这是一个重要的功能 - 我不记得上次我真的必须搜索一个演员. (2认同)
  • @JohnPhuNguyen您可以通过这种方式获得很多误报。即从函数原型或函数指针定义等中获取。此外,不可能找到“所有强制类型转换”,而可以找到“所有`reinterpret_cast`s”并进行分析。 (2认同)
  • 前几天我刚刚经历过这个,我将所有 C 风格的强制转换更改为 C++ 强制转换。找到所有各种可能的数据类型变化以及括号内部和周围的空格是一个很大的痛苦。简单的搜索和替换并不容易。 (2认同)
  • @deLock 我当时正在使用正则表达式搜索。这仍然是一个巨大的 PITA 任务要做。几个月后,我仍然在这里发现我第一次错过的案例。 (2认同)

Rik*_*ika 165

简而言之:

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

更多说明:

静态强制转换执行兼容类型之间的转换.它类似于C风格的演员表,但更具限制性.例如,C样式转换将允许整数指针指向char.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes
Run Code Online (Sandbox Code Playgroud)

由于这会导致指向已分配内存的1个字节的4字节指针(指向4字节数据类型的指针),因此写入此指针将导致运行时错误或将覆盖某些相邻内存.

*p = 5; // run-time error: stack corruption
Run Code Online (Sandbox Code Playgroud)

与C样式转换相反,静态转换将允许编译器检查指针和指针数据类型是否兼容,这允许程序员在编译期间捕获这种不正确的指针赋值.

int *q = static_cast<int*>(&c); // compile-time error
Run Code Online (Sandbox Code Playgroud)

您还可以在有关C++演员表的更多说明中查看此页面:单击此处

  • 我认为代替"4字节指针"意味着"指向4字节数据类型的指针" (14认同)
  • @TonyParker那是因为那行没有错。 (2认同)

Eug*_*ota 15

请参阅C++强制转换运算符的比较.

但是,对于各种不同的转换操作使用相同的语法可能会使程序员的意图不清楚.

此外,在大型代码库中找到特定类型的强制转换可能很困难.

对于所有需要的只是简单转换的情况,C风格演员的普遍性可能是过度的.在具有不同功率的几个不同铸造操作员之间进行选择的能力可以防止程序员无意中铸造到不正确的类型.


小智 14

struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}
Run Code Online (Sandbox Code Playgroud)

  • 您能否详细说明您的答案,添加一些关于您提供的解决方案的更多描述? (5认同)

Yin*_*ong 7

一篇很棒的文章,解释了C / C ++中的不同强制类型转换以及C样式强制类型的真正作用:https : //anteru.net/blog/2007/12/18/200/index.html

C样式转换,使用(type)变量语法。有史以来最糟糕的发明。尝试按此顺序执行以下强制转换:(另请参见C ++ Standard,5.4 expr.cast第5段)

  1. const_cast
  2. static_cast
  3. static_cast后跟const_cast
  4. reinterpret_cast
  5. reinterpret_cast之后是const_cast


Dou*_* T. 5

由于有许多不同类型的强制转换,每种强制转换都有不同的语义,因此 static_cast<> 允许您说“我正在进行从一种类型到另一种类型的合法转换”,例如从 int 到 double 的转换。一个普通的 C 风格的演员阵容可以意味着很多事情。你是向上/向下投射吗?您正在重新解释指针吗?


kir*_*off 5

static_cast在编译时检查转换不是明显不兼容的类型之间.与此相反dynamic_cast,在运行时不会检查类型兼容性.此外,static_cast转换不一定安全.

static_cast 用于将指针转换为基类,指向派生类的指针,或本机类型之间的转换,例如enum to int或float to int.

用户static_cast必须确保转换是安全的.

C风格的强制转换不会在编译或运行时执行任何检查.