类型信息,动态类型标识,虚函数调度不需要。
虚拟函数调度通常通过每个对象中的一个 vtable 指针来实现,其中该指针指向一个特定类型的函数实现指针表(“vtable”)。
dynamic_cast 和 typeid 需要类型信息。
对于返回类型信息的typeid,该信息必须存在于可执行文件的某个位置。当您关闭信息的存储时,它就不会在那里被检索。但是dynamic_cast呢?
在最简单的情况下,dynamic_cast 是从某个基类型引用向下转换为派生类型引用 D&。派生类型不必是对象的最派生类型。因此,对于现在通用的动态调度 vtable 方案,对象的 vtable 指针不需要指向 D 类型的 vtable,因此不提供简单的成功检查。
对于仅限于单一继承的语言,纯粹向下转换的情况可以通过使用 vtable 本身作为类型标识符来解决,方法是通过 vtable 中的父指针搜索(单一)继承链。
图片中的多重继承使事情变得复杂。例如,如果类Derived 继承自Base1 和Base2,两者都是多态的,那么Derived 类的vtable 不能简单地扩展Base1 的vtable 和 em> 只需扩展 Base2 的 vtable。因此,如果Derived 虚表扩展了Base1,那么当将Derived* 重新解释为Base2* 时,指向对象的Derived 虚表指针将不再用作指向静态已知对象的指针类的虚表。
因此一个后果是,在存在多重继承的情况下,转换为基类型引用并不总是对指针类型进行简单的重新解释——可能必须调整指针值。
如何做到这一点非常不明显,以至于 Bjarne Stroustrup 不得不向自己证明,在向语言添加多重继承之前,可以实现多重继承的 vtable 方案。
我不知道当前的编译器如何处理它,特别是对于dynamic_cast,但由于简单的 vtable 父指针不适用于多重继承,逻辑上编译器无法通过该机制做到这一点:一些额外的支持数据需要结构、RTTI 信息。
"我想知道如何向下转换,然后检查它是否是指向正确类型的指针。不过,我无法修改所涉及的类或打开 RTTI。
如果您无法更改代码或打开 RTTI,您通常无法获取所需的信息。
在您控制所有对象实例化的特殊情况下,原则上您可以为每个对象维护一个单独的类型信息映射,但效率极低。