在C ++中,为什么使用static_cast< int>(x)而不是(int)x? [英] In C++, why use static_cast<int>(x) instead of (int)x?
问题描述
我听说过,在C ++中, static_cast
函数应该优先于C风格或简单的函数式转换。这是真的?为什么?
I've heard that, in C++, 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.
A 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 a 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).
A 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 CMyClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
现在,这两种编译方式相同:
Now, these two are compiled the same way:
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!!!
正如你所看到的,没有一个简单的方法来区分两种情况,所有的类都涉及。
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风格的cast。几乎不可能编写一个自动化工具,需要找到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.
这篇关于在C ++中,为什么使用static_cast< int>(x)而不是(int)x?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!