C++ Dynamic Cast

2024年8月28日 | 阅读 4 分钟

C++ 中的类型转换运算符 dynamic_cast 用于将指针或引用从一种类型更改为另一种类型。在运行时,可以使用 dynamic_cast 运算符 安全地向下转换多态类型。多态类型的类层次结构至少包含一个虚函数。

语法

使用 dynamic_cast 的语法如下:

其中 “expression” 是正在进行类型转换的表达式,“new_type” 表示 expression 正在被转换到的类型。expression 中必须存在指向多态类型的 指针 或引用。

为了确认被寻址或引用的对象确实是指定的 new_typedynamic_cast 运算符将执行运行时类型检查。如果转换不可能,dynamic_cast 运算符将返回一个 空指针(对于指针转换)或抛出 std::bad_cast 异常(对于引用转换)。

示例

演示如何使用 “dynamic_cast” 执行向下转换的代码片段

输出

Woof woof!

说明

在此示例中,我们创建了一个类层次结构:AnimalDogCat。Dog 和 Cat 都 继承Animal,其中 Dog 有一个名为 bark 的函数,而 Cat 有一个名为 meow 的函数。

我们在 "main" 中创建一个新的 Dog 对象,并将其地址分配给 Animal* 类型的指针。之后,我们尝试使用 dynamic_cast 将 Animal* 指针 转换为 Dog* 指针。因为指向的对象是 Dog 对象,所以 dynamic_cast 成功并返回一个有效的 Dog* 指针。之后,我们检查 Dog* 指针 不是 nullptr(即转换成功),并使用 dogPtr 调用 Dog 对象的 bark 函数。最后,我们删除 Animal* 指针,这也删除了 Dog 对象

注意:Dynamic_cast 仅用于多态类型,不应与非多态类型一起使用。此外,应尽量减少 dynamic_cast 的使用,因为它可能表明类层次结构设计不佳。一般来说,最好使用虚函数和继承来实现所需的行为,而不是依赖于类型转换。

Dynamic_cast 运算符的一些重要点如下:

  • dynamic_cast 也可以与引用而不是指针一起使用。语法与指针相同,只是将指针 表示法 * 替换为 引用表示法 &。 例如:dynamic_cast
  • 如果使用 dynamic_cast 将指向类类型的指针或引用转换为 void 指针引用,它将执行 reinterpret_cast 而不是 dynamic_cast
  • dynamic_cast 只能与指针或引用一起使用,不能与值一起使用。
  • 由于需要运行时类型检查,dynamic_cast 的性能可能比其他类型的类型转换慢。
  • dynamic_cast 只能用于其类层次结构中至少有一个虚函数的类。这是因为 虚函数表 (vtable) 用于执行运行时类型检查。
  • dynamic_cast 可用于从派生类转换为基类,但不建议这样做。相反,请使用 static_cast 或依赖隐式转换。
  • 如果使用 dynamic_cast 将空指针转换为 指针类型,则结果将是目标类型的空指针。
  • 当使用 dynamic_cast 与指针时,如果转换失败(即,指针不是目标类型),结果将是一个空指针。这与 reinterpret_cast 不同,reinterpret_cast 将执行未经检查的转换,这可能导致未定义的行为。
  • 如果使用 dynamic_cast 与引用进行转换失败,将抛出 bad_cast 异常。因此,重要的是使用异常处理来适当捕获和处理此异常。
  • dynamic_cast 还可以用于执行交叉转换,这涉及在两个不相关但共享共同基类的类之间进行转换。例如,假设您有两个 类 AB,它们都继承自一个共同的基 类 C。如果您有一个指向 A 对象 的指针或引用,并且您想将其转换为 B 指针引用(反之亦然),您可以使用 dynamic_cast。然而,这种类型的转换可能很复杂,需要仔细考虑类层次结构。
  • dynamic_cast 是一种相对昂贵的操作,因此在性能关键代码中应有效地使用它。在某些情况下,最好使用替代技术,例如 模板元编程编译时多态性