我有兴趣了解,一般来说,运行时在使用dynamic_cast应用向下转型时如何检查基类是否实际上指向派生类。 我知道多态类的每个虚拟表也包含 RTTI(以 type_info 指针的形式)。
最佳答案
每个编译器在实现上都会略有不同,但我将使用 MSVC 作为引用,因为它们可以轻松地使用 VS 提供源代码。
您可以通过转到 Visual Studio 安装并转到 /Community/VS/Tools/MSVC/${VERSION}/crt/src/vcruntime/rtti 来查看有关 MSVC 如何执行此操作的所有详细信息。 .cpp
编译器将在内部转换dynamic_cast
来调用函数__RTDynamicCast
(如果尝试转换为void,则调用
),这将获取目标类型和源类型的 RTTI 信息。 __RTCastToVoid
*_RTTITypeDescriptor
结构中的关键元素是完全修饰的名称。然后,它将根据输入类型是否具有单继承、多重继承或虚拟继承来分派(dispatch)到 3 种不同实现之一。
对于单继承FindSITargetTypeInstance
将遍历基类类型列表,如果通过指针比较找到匹配项,它将返回类描述符。如果它无法通过指针比较找到匹配项,它将使用字符串比较再次尝试。
对于多重继承,FindMITargetTypeInstance
将以深度优先、从左到右的顺序遍历类层次结构,直到看到源类型和目标类型的描述符。每次比较都是通过 TypeidsEqual 完成的,它将首先尝试进行指针比较,但会立即回退到字符串比较,这与单继承不同,因为单继承很可能在 2 个单独的循环中执行此操作指针会匹配。
对于虚拟继承,FindVITargetTypeInstance
将遍历整个类层次结构。这是三者中最慢的,因为由于潜在的菱形继承(钻石问题),它无法提前退出。每次比较都是通过 TypeidsEqual
完成的。
一旦找到类型的描述符,它将使用它来计算从源指针到目标指针的偏移量。
总体而言,代码相当简单,并且文档记录得非常好,尽管我确实遗漏了一些细微差别,例如检查基类是否是公开派生的,或者区分向下转换、向上转换和交叉转换。
关于c++ - dynamic_cast 向下转型 : How does the runtime check whether Base points to Derived?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70865904/