MST
星途 面试题库

面试题:C++ 类的多态实现原理

请阐述在C++中,如何通过类来实现多态?虚函数、纯虚函数以及虚表在多态实现过程中分别起到什么作用?请结合代码示例说明。
33.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 通过类实现多态的方式

在C++ 中,通过基类指针或引用指向派生类对象来实现多态。基类中定义虚函数,派生类重写这些虚函数。当通过基类指针或引用调用虚函数时,会根据实际指向的对象类型来决定调用哪个类的虚函数版本,从而实现多态。

2. 虚函数、纯虚函数以及虚表的作用

  • 虚函数:在基类中使用 virtual 关键字声明的函数,允许派生类重写该函数。虚函数为多态提供了基础,使得通过基类指针或引用调用函数时,能够根据对象的实际类型动态绑定到合适的函数版本。
  • 纯虚函数:是一种特殊的虚函数,在声明时初始化为 0 (virtual void func() = 0;)。包含纯虚函数的类为抽象类,不能实例化对象。纯虚函数主要用于定义接口,强制派生类必须重写该函数,进一步规范多态行为。
  • 虚表:每个包含虚函数的类都有一个虚表(Virtual Table,简称 vtable)。虚表是一个函数指针数组,存储了类中虚函数的地址。当创建一个对象时,对象内部会有一个虚表指针(vptr),指向该类的虚表。在运行时,通过对象的虚表指针找到虚表,进而根据虚表中存储的函数地址调用合适的虚函数,实现动态绑定。

3. 代码示例

#include <iostream>

// 基类
class Animal {
public:
    // 虚函数
    virtual void speak() {
        std::cout << "Animal speaks" << std::endl;
    }
};

// 派生类
class Dog : public Animal {
public:
    // 重写基类的虚函数
    void speak() override {
        std::cout << "Dog barks" << std::endl;
    }
};

// 派生类
class Cat : public Animal {
public:
    // 重写基类的虚函数
    void speak() override {
        std::cout << "Cat meows" << std::endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->speak(); // 调用 Dog 的 speak 函数
    animal2->speak(); // 调用 Cat 的 speak 函数

    delete animal1;
    delete animal2;
    return 0;
}

在上述代码中,Animal 类中的 speak 函数是虚函数。DogCat 类继承自 Animal 类,并分别重写了 speak 函数。在 main 函数中,通过 Animal 指针指向不同派生类对象,调用 speak 函数时,实现了根据对象实际类型的动态绑定,展示了多态性。