2

我是研究高级 C++ 主题的新手,所以如果问题听起来太明显,请原谅我。

我一直在阅读有关在 C++ 中我们可以在运行时获取对象类型信息的各种方法,通常称为 RTTI。

但是,我对它是如何工作的感到困惑。我读过一些在解释 RTTI 时经常提到的东西。其中之一是使用 dynamic_cast<> 将对象动态地转换为其他对象。另一种是在运行时使用 typeid 来确定对象的类型。

我想知道使用 typeid 是否是在 C++ 中实现 RTTI 的正确方法,如果是,那么 typeid 运算符实际上如何能够在运行时确定对象的类型(它是否分析了对象 blob 中的位模式记忆? )

如果使用 typeid 不是正确的方法,那么请提出一些其他的实现方法。

4

2 回答 2

7

重要提示:
理想情况下,如果您需要识别对象的类型,您需要重新审视您的设计,因为您很可能错过了那里的某些东西并且您违反了OOP 的SOLID规则。

C++ 标准提供dynamic_casttypeid作为确定对象类型的两种方法。两者都有其优点和局限性。它们如何识别类型是依赖于实现的细节,但通常它们通过在对象的 vtable 中维护指向类型信息结构的指针来做到这一点。如果您完全不知道 vtable 是什么,Marshal Clines C++ Faq在这里提供了一个很好的解释。

您可以在 C++ 性能技术报告中找到大多数编译器使用的实现细节

相关摘录:

5.3.7 类型信息

给定一个多态类的对象(一个至少有一个虚函数的类),可以通过使用 typeid 操作符得到一个 type_info 对象。原则上,这是一个简单的操作,它涉及找到虚函数表,通过找到该对象所属的最派生类对象,然后从该对象的虚函数表(或等效项)中提取指向 type_info 对象的指针)。


5.3.8 动态投射

给定一个指向多态类对象的指针,可以使用 dynamic_cast 转换为指向同一派生类对象的另一个基子对象的指针。原则上,该操作涉及找到虚函数表,通过找到该对象所属的最派生类对象,然后使用与该对象关联的类型信息来确定是否允许转换(强制转换),最后对 this 指针进行任何必要的调整。原则上,这种检查涉及对描述最派生类的基类的数据结构的遍历。因此,dynamic_cast 的运行时成本可能取决于所涉及的两个类在类层次结构中的相对位置。

于 2013-04-28T18:42:25.863 回答
2

RTTI 仅适用于具有虚函数的类的实例。在这种情况下,编译器会在类中添加一个特殊成员,调用虚拟表指针。每个具有虚函数的类都有自己的虚表。通过检查指向哪个虚拟表,可以确定对象的具体类型。

于 2013-04-28T18:41:28.523 回答