MST

星途 面试题库

面试题:C++ 中虚函数如何实现多态性

请详细阐述在 C++ 中虚函数是怎样支持多态性的,并且通过一段简单代码示例说明虚函数、继承和多态性之间的关系。
49.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

虚函数对多态性的支持原理

在 C++ 中,虚函数通过动态绑定(dynamic binding)来支持多态性。当一个基类指针或引用指向一个派生类对象时,通过该指针或引用调用虚函数,实际调用的是派生类中重写的虚函数版本,而不是基类中的版本。这一机制是基于运行时确定对象的实际类型,而不是编译时指针或引用的静态类型。

C++ 实现动态绑定的关键在于虚函数表(vtable)和虚函数表指针(vptr)。每个包含虚函数的类都有一个虚函数表,其中存储了该类所有虚函数的地址。每个对象都有一个虚函数表指针,指向其所属类的虚函数表。当通过基类指针或引用调用虚函数时,程序会根据对象的 vptr 找到对应的 vtable,然后从 vtable 中获取实际要调用的虚函数地址,从而实现对正确虚函数版本的调用。

代码示例

#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;
    }
};

void makeSound(Animal& animal) {
    animal.speak();
}

int main() {
    Animal animal;
    Dog dog;
    Cat cat;

    makeSound(animal); // 输出 "Animal speaks"
    makeSound(dog);    // 输出 "Dog barks"
    makeSound(cat);    // 输出 "Cat meows"

    return 0;
}

代码说明

  1. 虚函数:在 Animal 类中,speak 函数被声明为 virtual,这使其成为虚函数。
  2. 继承DogCat 类继承自 Animal 类,它们都重写了 Animal 类中的 speak 虚函数。
  3. 多态性makeSound 函数接受一个 Animal 类的引用作为参数。在 main 函数中,通过 makeSound 函数分别传入 AnimalDogCat 对象,尽管函数参数类型为 Animal,但实际调用的是每个对象对应的 speak 函数版本,展示了多态性。这是因为 speak 函数是虚函数,通过动态绑定实现了运行时多态。