有什么理由static_cast<>
比 C 风格的铸造更喜欢吗?它们是等价的吗?有什么速度差异吗?
7 回答
C++ 风格转换由编译器检查。C 风格的强制转换不会也可能在运行时失败。
此外,可以轻松搜索 c++ 样式转换,而很难搜索 c 样式转换。
另一个很大的好处是 4 种不同的 C++ 风格转换更清楚地表达了程序员的意图。
在编写 C++ 时,我几乎总是使用 C++ 而不是 C 风格。
简而言之:
static_cast<>()
为您提供编译时检查能力,C-Style cast 没有。static_cast<>()
更具可读性,并且可以在 C++ 源代码中的任何地方轻松发现,C_Style cast 不是。- 使用 C++ 强制转换可以更好地传达意图。
更多解释:
静态转换执行兼容类型之间的转换。它类似于 C 风格的演员表,但更具限制性。例如,C 风格的转换将允许一个整数指针指向一个字符。
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
由于这会导致 4 字节指针(指向 4 字节数据类型的指针)指向 1 字节的已分配内存,因此写入该指针将导致运行时错误或将覆盖一些相邻的内存。
*p = 5; // run-time error: stack corruption
与 C 风格的转换相比,静态转换将允许编译器检查指针和指针数据类型是否兼容,这允许程序员在编译期间捕获这种不正确的指针分配。
int *q = static_cast<int*>(&c); // compile-time error
您还可以查看此页面以获取有关 C++ 强制转换的更多说明:单击此处
请参阅C++ 强制转换运算符的比较。
但是,对各种不同的强制转换操作使用相同的语法可能会使程序员的意图不清楚。
此外,在大型代码库中很难找到特定类型的演员表。
对于只需要简单转换的情况,C 样式转换的通用性可能会过大。在几个不同权力程度的不同转换运算符之间进行选择的能力可以防止程序员无意中转换为不正确的类型。
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!
}
一篇很棒的文章,解释了 C/C++ 中的不同类型转换,以及 C 风格类型转换的真正作用:https ://anteru.net/blog/2007/12/18/200/index.html
C 样式转换,使用(类型)变量语法。有史以来最糟糕的发明。这会尝试按以下顺序执行以下强制转换:(另请参见 C++ 标准,5.4 expr.cast 第 5 段)
- const_cast
- static_cast
- static_cast 后跟 const_cast
- reinterpret_cast
- reinterpret_cast 后跟 const_cast
static_cast
在编译时检查转换不在明显不兼容的类型之间。与 相反dynamic_cast
,在运行时不检查类型兼容性。此外,static_cast
转换不一定是安全的。
static_cast
用于从指向基类的指针转换为指向派生类的指针,或在本机类型之间转换,例如 enum 到 int 或 float 到 int。
用户static_cast
必须确保转换是安全的。
C 风格的转换不执行任何检查,无论是在编译时还是在运行时。
由于有许多不同类型的转换,每种都具有不同的语义,因此 static_cast<> 允许您说“我正在从一种类型到另一种类型的合法转换”,例如从 int 到 double。一个普通的 C 风格的演员表可能意味着很多事情。你是向上/向下铸造吗?你在重新解释指针吗?