MST

星途 面试题库

面试题:C++派生类中虚函数重写及多态实现细节

假设你有一个基类`Base`包含一个虚函数`virtual void func()`,然后派生出`Derived`类重写这个函数。请阐述在使用基类指针或引用指向派生类对象时,多态是如何实现的,包括编译器和运行时分别做了哪些工作。同时,说明`override`关键字在这种场景下的作用及使用方法。
14.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 多态的实现
    • 编译器工作
      • 当编译器遇到基类指针或引用指向派生类对象,且调用虚函数func()时,编译器会生成代码,通过对象的虚函数表指针(vptr)来间接调用函数。在编译阶段,编译器为每个包含虚函数的类创建一个虚函数表(vtable),虚函数表是一个函数指针数组,其中每个元素对应一个虚函数的地址。对于派生类,如果重写了基类的虚函数,派生类的虚函数表中相应的函数指针会被替换为派生类重写函数的地址。每个包含虚函数的类的对象都包含一个指向其虚函数表的指针(vptr)。
    • 运行时工作
      • 在运行时,当通过基类指针或引用调用虚函数func()时,程序首先根据对象的vptr找到对应的虚函数表。然后,根据虚函数表中存储的函数指针,调用实际应该执行的函数(即派生类重写的func()函数,如果派生类重写了该函数)。这就实现了动态绑定,使得程序能够根据对象的实际类型来调用正确的函数版本,从而实现多态。
  2. override关键字
    • 作用override关键字用于显式地表明派生类中的函数是对基类中虚函数的重写。它有助于编译器检查派生类中的函数是否确实重写了基类的虚函数。如果使用override修饰的函数在基类中不存在对应的虚函数,或者函数签名与基类中的虚函数不匹配,编译器会报错。这有助于在编译阶段发现错误,提高代码的健壮性。
    • 使用方法:在派生类中重写虚函数时,在函数声明的参数列表后加上override关键字。例如:
class Base {
public:
    virtual void func() {}
};
class Derived : public Base {
public:
    void func() override {
        // 派生类重写的func函数实现
    }
};