cast <int>(x)而不是(int)x?
我听说static_cast
函数应该优先于C风格或简单的函数式风格。 这是真的? 为什么?
主要原因是经典的C语言转换对我们所称的static_cast<>()
, reinterpret_cast<>()
, const_cast<>()
和dynamic_cast<>()
没有区别。 这四件事情完全不同。
static_cast<>()
通常是安全的。 在语言中有一个有效的转换,或者使其成为可能的适当的构造函数。 唯一有点风险的是当你抛弃一个继承的类; 您必须确保该对象实际上是您声称它的后代,通过语言外部的方式(如对象中的标志)。 只要结果被检查(指针)或者可能的异常被考虑(参考), dynamic_cast<>()
就是安全的。
reinterpret_cast<>()
(或const_cast<>()
)另一方面总是危险的。 你告诉编译器:“相信我:我知道这看起来不像foo
(这看起来好像不可变),但它是”。
第一个问题是,几乎不可能知道哪一个会出现在C风格的演员中,而不会查看大量且分散的代码片段并了解所有规则。
我们假设这些:
class CMyClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
现在,这两个编译方式相同:
CMyClass *pMyObject;
pMyObject = static_cast<CMyClass*>(pSomething); // Safe; as long as we checked
pMyObject = (CMyClass*)(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风格的演员阵容更危险,而且更难找到他们,以确保他们是正确的。
一个实用的提示:如果您打算整理项目,可以轻松搜索源代码中的static_cast关键字。
总之 :
static_cast<>()
给你一个编译时检查能力,C-Style static_cast<>()
不。 static_cast<>()
可以很容易地在C ++源代码中的任何位置被发现; 相比之下,C_Style演员更难以发现。 更多解释 :
静态转换执行兼容类型之间的转换。 它类似于C风格的演员,但更具限制性。 例如,C风格的转换将允许一个整数指针指向一个字符。
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
由于这会产生指向分配内存1字节的4字节指针,因此写入此指针会导致运行时错误或覆盖某些相邻内存。
*p = 5; // run-time error: stack corruption
与C风格转换相反,静态转换将允许编译器检查指针和指针数据类型是否兼容,这允许程序员在编译期间捕获这个不正确的指针分配。
int *q = static_cast<int*>(&c); // compile-time error
阅读更多信息:
static_cast <>和C风格转型有什么区别
和
定期投射vs. static_cast vs. dynamic_cast