MST
星途 面试题库

面试题:C++虚函数重写与多态的实现细节

假设你有一个基类`Base`包含虚函数`virtual void func()`,以及派生类`Derived`重写了该虚函数。当通过`Base* ptr = new Derived(); ptr->func();`调用函数时,详细说明编译器和运行时系统是如何实现多态性的?在这个过程中,虚函数表(vtable)起到了什么作用?
30.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 编译器阶段
    • 当编译器看到Base* ptr = new Derived();时,它会为BaseDerived类分别构建虚函数表(vtable)。在Base类的虚函数表中,会有func函数的地址,这里是Base::func的地址(因为它是虚函数,需要通过虚函数表来调用)。
    • 对于Derived类,编译器会检查其对基类虚函数的重写情况。由于Derived重写了func函数,在Derived类的虚函数表中,对应func函数的条目会被替换为Derived::func的地址。
    • 当执行Base* ptr = new Derived();时,编译器会为Derived对象分配内存,在对象的内存布局中,对象的首地址处会存放一个指针,该指针指向Derived类的虚函数表(vtable)。
  2. 运行时阶段
    • 当执行ptr->func();时,运行时系统首先会根据ptr所指向对象的首地址,找到其虚函数表指针。由于ptr指向的是Derived类对象,所以这个虚函数表指针指向Derived类的虚函数表。
    • 然后,运行时系统在虚函数表中查找func函数对应的条目,因为是Derived类的虚函数表,这里找到的是Derived::func的地址。
    • 最后,运行时系统通过找到的Derived::func的地址调用该函数,从而实现了多态性。
  3. 虚函数表(vtable)的作用
    • 实现多态性:虚函数表为运行时系统提供了一种机制,通过对象的虚函数表指针,运行时系统能够在运行时动态地确定应该调用哪个函数版本。对于不同类型的对象(如Base对象和Derived对象),即使通过基类指针来操作,也能根据对象实际类型对应的虚函数表找到正确的虚函数实现。
    • 存储虚函数地址:虚函数表存储了类中所有虚函数的地址。在类的继承体系中,每个类都有自己的虚函数表,它记录了该类及其基类虚函数在该类中的实现地址,使得运行时系统能够高效地进行函数调用的动态绑定。