我已经编写 C 和 C++ 代码将近 20 年了,但是这些语言的某一方面我从未真正理解过。我显然使用过常规演员,即
MyClass *m = (MyClass *)ptr;
到处都是,但似乎还有另外两种类型的演员表,我不知道有什么区别。以下代码行之间有什么区别?
MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);
原文由 Graeme Perrow 发布,翻译遵循 CC BY-SA 4.0 许可协议
static_cast
static_cast
用于您基本上想要反转隐式转换的情况,有一些限制和补充。static_cast
不执行运行时检查。如果您知道您引用了特定类型的对象,则应该使用它,因此不需要检查。例子:在这个例子中,你知道你传递了一个
MyClass
对象,因此不需要运行时检查来确保这一点。dynamic_cast
dynamic_cast
当您不知道对象的动态类型是什么时很有用。如果引用的对象不包含转换为基类的类型,则返回空指针(当您转换为引用时,在这种情况下会引发bad_cast
异常)。如果 参数类型不是多态的,则 不能 使用
dynamic_cast
进行向下转换(转换为派生类)。例如,以下代码无效,因为Base
不包含任何虚函数:“向上转换”(转换为基类)对于
static_cast
和dynamic_cast
始终有效,并且也没有任何转换,因为“向上转换”是隐式的转换(假设基类是可访问的,即它是public
继承)。常规演员表
这些演员表也称为 C 风格演员表。 C 风格的演员表基本上等同于尝试一系列 C++ 演员表,并采用第一个有效的 C++ 演员表,而无需考虑
dynamic_cast
。不用说,这更强大,因为它结合了所有const_cast
,static_cast
和reinterpret_cast
,但它也不安全dynamic_cast
。此外,C 风格的转换不仅允许您执行此操作,而且还允许您安全地转换为私有基类,而“等效”
static_cast
序列将为您提供编译时间错误。有些人更喜欢 C 风格的演员,因为它们很简洁。我只将它们用于数字类型转换,并在涉及用户定义类型时使用适当的 C++ 类型转换,因为它们提供了更严格的检查。