MST

星途 面试题库

面试题:C++ 虚函数表与运行时类型识别(RTTI)的关联及实现原理

阐述 C++ 虚函数表与运行时类型识别(RTTI)之间的内在联系。说明 RTTI 是如何借助虚函数表实现的,包括 typeid 运算符和 dynamic_cast 运算符在这种机制下的具体实现原理,以及可能涉及到的底层数据结构和操作。
10.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

虚函数表与 RTTI 的内在联系

  1. 虚函数表:在 C++ 中,当一个类包含虚函数时,编译器会为该类生成一个虚函数表(vtable)。每个包含虚函数的对象都有一个指向其所属类虚函数表的指针(vptr)。虚函数表是一个函数指针数组,存储了类中虚函数的地址。当通过基类指针或引用调用虚函数时,程序会根据 vptr 找到对应的虚函数表,进而调用正确的函数。
  2. RTTI:运行时类型识别(RTTI)允许程序在运行时确定对象的实际类型。RTTI 主要通过 typeid 运算符和 dynamic_cast 运算符来实现。RTTI 依赖于虚函数机制,因为虚函数表为实现 RTTI 提供了关键信息。

RTTI 借助虚函数表的实现

  1. typeid 运算符
    • 原理:当对一个多态类型的对象或指针使用 typeid 运算符时,如果该对象是通过指针访问且指针类型为多态类型(即包含虚函数的类的指针),编译器会借助虚函数表来确定对象的实际类型。虚函数表的第一个条目通常存放了指向该类类型信息(type_info 对象)的指针。当使用 typeid 时,程序会沿着对象的 vptr 找到虚函数表,然后从虚函数表的第一个位置获取指向 type_info 对象的指针,通过这个 type_info 对象可以获取对象的实际类型信息,如类名等。
    • 底层数据结构:涉及虚函数表(vtable)和 type_info 结构体。type_info 结构体存储了类型的相关信息,如类型名称等。
  2. dynamic_cast 运算符
    • 原理:当使用 dynamic_cast 进行从基类指针或引用到派生类指针或引用的转换时,如果是多态类型,它会借助虚函数表来进行类型检查。它首先通过对象的 vptr 找到虚函数表,然后从虚函数表获取类型信息,与目标类型进行比较。如果类型匹配,则转换成功,返回指向派生类对象的指针或引用;如果不匹配,则返回空指针(对于指针转换)或抛出 std::bad_cast 异常(对于引用转换)。
    • 底层操作:在运行时遍历虚函数表获取类型信息并进行类型比较。如果是指针转换,在类型匹配时,计算目标对象在内存中的偏移量,以正确调整指针。

总结

虚函数表为 RTTI 的实现提供了关键的运行时信息。typeid 和 dynamic_cast 运算符借助虚函数表中的类型信息指针来确定对象的实际类型,实现运行时类型识别和安全的类型转换。 虚函数表、vptr 以及 type_info 结构体等底层数据结构共同协作,完成 RTTI 的各项功能。