Why use static_castlt;intgt;(x) instead of (int)x?(为什么使用 static_castint(x) 而不是 (int)x?)
问题描述
我听说 static_cast
函数应该比 C 风格或简单函数风格的转换更受欢迎.这是真的?为什么?
I've heard that the static_cast
function should be preferred to C-style or simple function-style casting. Is this true? Why?
推荐答案
主要的原因是经典的 C 强制转换没有区分我们所说的 static_cast<>()
, reinterpret_cast<>()
、const_cast<>()
和 dynamic_cast<>()
.这四件事完全不同.
The main reason is that classic C casts make no distinction between what we call static_cast<>()
, reinterpret_cast<>()
, const_cast<>()
, and dynamic_cast<>()
. These four things are completely different.
static_cast<>()
通常是安全的.语言中有一个有效的转换,或者一个合适的构造函数使之成为可能.唯一有点冒险的时候是当你转换到一个继承的类时;您必须通过语言外部的方式(如对象中的标志)确保该对象实际上是您声称的后代.只要检查结果(指针)或考虑可能的异常(参考),dynamic_cast<>()
就是安全的.
A static_cast<>()
is usually safe. There is a valid conversion in the language, or an appropriate constructor that makes it possible. The only time it's a bit risky is when you cast down to an inherited class; you must make sure that the object is actually the descendant that you claim it is, by means external to the language (like a flag in the object). A dynamic_cast<>()
is safe as long as the result is checked (pointer) or a possible exception is taken into account (reference).
另一方面,reinterpret_cast<>()
(或const_cast<>()
)总是危险的.你告诉编译器:相信我:我知道这看起来不像 foo
(这看起来好像它不可变),但它是".
A reinterpret_cast<>()
(or a const_cast<>()
) on the other hand is always dangerous. You tell the compiler: "trust me: I know this doesn't look like a foo
(this looks as if it isn't mutable), but it is".
第一个问题是,如果不查看大量分散的代码并了解所有规则,几乎不可能知道在 C 风格的强制转换中会出现哪一个.
The first problem is that it's almost impossible to tell which one will occur in a C-style cast without looking at large and disperse pieces of code and knowing all the rules.
让我们假设这些:
class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
现在,这两个编译方式相同:
Now, these two are compiled the same way:
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
但是,让我们看看这个几乎相同的代码:
However, let's see this almost identical code:
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!!!
如您所见,如果不了解所涉及的所有类,就没有简单的方法来区分这两种情况.
As you can see, there is no easy way to distinguish between the two situations without knowing a lot about all the classes involved.
第二个问题是 C 风格的强制转换太难定位了.在复杂的表达式中,很难看到 C 风格的强制转换.如果没有完整的 C++ 编译器前端,几乎不可能编写需要定位 C 样式转换(例如搜索工具)的自动化工具.另一方面,很容易搜索static_cast<"或reinterpret_cast<".
The second problem is that the C-style casts are too hard to locate. In complex expressions it can be very hard to see C-style casts. It is virtually impossible to write an automated tool that needs to locate C-style casts (for example a search tool) without a full blown C++ compiler front-end. On the other hand, it's easy to search for "static_cast<" or "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 风格的强制转换更危险,而且要找到它们以确保它们是正确的要困难得多.
That means that, not only are C-style casts more dangerous, but it's a lot harder to find them all to make sure that they are correct.
这篇关于为什么使用 static_cast<int>(x) 而不是 (int)x?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么使用 static_cast<int>(x) 而不是 (int)x?
基础教程推荐
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++,'if' 表达式中的变量声明 2021-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01