面试题答案
一键面试虚函数对多态性的支持原理
在 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;
}
代码说明
- 虚函数:在
Animal
类中,speak
函数被声明为virtual
,这使其成为虚函数。 - 继承:
Dog
和Cat
类继承自Animal
类,它们都重写了Animal
类中的speak
虚函数。 - 多态性:
makeSound
函数接受一个Animal
类的引用作为参数。在main
函数中,通过makeSound
函数分别传入Animal
、Dog
和Cat
对象,尽管函数参数类型为Animal
,但实际调用的是每个对象对应的speak
函数版本,展示了多态性。这是因为speak
函数是虚函数,通过动态绑定实现了运行时多态。