RTTI,即Run-Time Type Information(运行时类型信息),是 C++ 提供的一种机制,用于在程序运行时获取和使用多态对象的实际类型信息

RTTI的作用:

  • 多态性支持: 当使用基类指针或引用指向派生类对象时,能够识别出对象的实际类型。
  • 类型安全转换: 允许在运行时进行(向下)类型转换,确保转换的安全性,避免了不安全的类型转换可能导致的错误。
  • 获取类型信息: 获取表达式的类型信息,包括基本类型和类类型。

C++提供了两个关键字typeiddynamic_cast以及一个type_info类来支持RTTI。

RTTI的原理:虚函数表

当一个类是多态类型时(即它至少包含一个虚函数):

  1. 编译器会为这个类创建一个虚函数表。这是一个静态的、只读的数据结构,它包含了该类所有虚函数的地址。当通过基类指针或引用调用虚函数时,程序会在运行时通过这个表找到正确的函数地址。
  2. 除了虚函数的地址,编译器还会在虚函数表中添加一个特殊的指针,这个指针指向一个std::type_info 对象。这个对象包含了该类的类型元数据,比如类型名称等。

dynamic_casttypeid 如何工作?

当在程序中调用dynamic_casttypeid时,编译器会生成代码,在运行时执行以下步骤:

  1. 获取对象的地址:程序首先通过基类指针或引用,找到对象实例在内存中的位置。
  2. 访问虚函数指针:每个多态对象的内存布局中,都包含一个虚函数表指针(vptr)。这个指针通常是对象实例的第一个成员,它指向该对象实际类型的虚函数表。
  3. 获取type_info指针:程序通过vptr找到虚函数表,然后从虚函数表中获取指向std::type_info对象的指针。

执行类型检查或获取名称:

  • 对于typeid:程序直接返回这个type_info对象。当你调用 .name() 或进行比较时,它会使用该对象中的信息。
  • 对于dynamic_cast:程序会比较目标类型和实际对象的type_info对象。如果它们匹配,或者实际类型是目标类型的派生类,则转换成功并返回有效的指针;否则,它会返回nullptr或抛出异常。