常规投放与static_cast与dynamic_cast
我从事C和C ++代码已有近20年的历史了,但是这些语言的一个方面我从未真正理解过。我显然已经使用了常规演员表
MyClass *m = (MyClass *)ptr;
各地,但似乎还有其他两种类型的演员,我不知道两者之间的区别。以下几行代码有什么区别?
MyClass *m = (MyClass *)ptr; MyClass *m = static_cast<MyClass *>(ptr); MyClass *m = dynamic_cast<MyClass *>(ptr);
解决方案
回答
dynamic_cast具有运行时类型检查,并且仅适用于引用和指针,而static_cast不提供运行时类型检查。有关完整的信息,请参见MSDN文章static_cast Operator。
回答
我们应该查看文章C ++编程/类型转换。
它很好地描述了所有不同的演员类型。以下摘自上述链接:
const_cast const_cast(expression) The const_cast<>() is used to add/remove const(ness) (or volatile-ness) of a variable. static_cast static_cast(expression) The static_cast<>() is used to cast between the integer types. 'e.g.' char->long, int->short etc. Static cast is also used to cast pointers to related types, for example casting void* to the appropriate type. dynamic_cast Dynamic cast is used to convert pointers and references at run-time, generally for the purpose of casting a pointer or reference up or down an inheritance chain (inheritance hierarchy). dynamic_cast(expression) The target type must be a pointer or reference type, and the expression must evaluate to a pointer or reference. Dynamic cast works only when the type of object to which the expression refers is compatible with the target type and the base class has at least one virtual member function. If not, and the type of expression being cast is a pointer, NULL is returned, if a dynamic cast on a reference fails, a bad_cast exception is thrown. When it doesn't fail, dynamic cast returns a pointer or reference of the target type to the object to which expression referred. reinterpret_cast Reinterpret cast simply casts one type bitwise to another. Any pointer or integral type can be casted to any other with reinterpret cast, easily allowing for misuse. For instance, with reinterpret cast one might, unsafely, cast an integer pointer to a string pointer.
回答
C样式转换将const_cast,static_cast和reinterpret_cast合并。
我希望C ++没有C样式的强制转换。 C ++强制转换正确突出(应有的表现;强制转换通常表示做错了事),并正确区分了强制转换执行的不同类型的转换。它们还允许编写类似外观的功能,例如boost :: lexical_cast,从一致性角度来看,这是相当不错的。
回答
仅供参考,我相信Bjarne Stroustrup的话是要避免使用C风格的强制转换,并且尽可能使用static_cast或者dynamic_cast。
Barne Stroustrup的C ++风格常见问题解答
采纳建议。我远非C ++专家。
回答
避免使用C-Style强制转换。
C风格的强制类型转换是const和重新解释强制类型转换的混合体,很难在代码中查找和替换。 C ++应用程序程序员应避免使用C样式强制转换。
回答
static_cast
" static_cast"用于我们基本上希望撤消隐式转换的情况,但有一些限制和添加条件。 static_cast
不执行任何运行时检查。如果我们知道我们引用的是特定类型的对象,则应使用此方法,这样就不必进行检查了。例子:
void func(void *data) { // Conversion from MyClass* -> void* is implicit MyClass *c = static_cast<MyClass*>(data); ... } int main() { MyClass c; start_thread(&func, &c) // func(&c) will be called .join(); }
在这个例子中,我们知道我们传递了一个MyClass对象,因此不需要任何运行时检查来确保这一点。
dynamic_cast
当我们不知道对象的动态类型是什么时,可以使用" dynamic_cast"。如果所引用的对象不包含强制转换为基类的类型,则它返回一个空指针(当强制转换为引用时,在这种情况下会抛出bad_cast
异常)。
if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) { ... } else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) { ... }
如果向下转换(广播到派生类)并且参数类型不是多态的,则不能使用" dynamic_cast"。例如,以下代码无效,因为Base
不包含任何虚函数:
struct Base { }; struct Derived : Base { }; int main() { Derived d; Base *b = &d; dynamic_cast<Derived*>(b); // Invalid }
"向上转换"(广播到基类)对于" static_cast"和" dynamic_cast"始终有效,并且也无需任何强制转换,因为"向上转换"是隐式转换。
常规演员
这些转换也称为C样式转换。 C样式强制转换基本上与尝试一系列C ++强制转换序列相同,并采用第一个有效的C ++强制转换,而无需考虑" dynamic_cast"。不用说,它结合了const_cast,static_cast和reinterpret_cast的所有功能,功能更加强大,但是它也不安全,因为它不使用dynamic_cast。
另外,C样式强制转换不仅允许我们执行此操作,而且还允许我们安全地强制转换为私有基类,而"等价"的" static_cast"序列将为此提供编译时错误。
由于简洁,有些人更喜欢C样式的演员表。我仅将它们用于数字转换,并在涉及用户定义类型时使用适当的C ++转换,因为它们提供了更严格的检查。