多态通过虚函数表和虚函数指针实现:1. 基类指针指向派生类对象并调用虚函数时,通过vptr找到对应vtable;2. 在vtable中查找函数地址并调用,实现运行时绑定。
在C++中,多态是通过虚函数和动态绑定实现的,其核心机制依赖于虚函数表(vtable)和虚函数指针(vptr)。下面用图解方式说明其工作原理。
要实现多态,必须满足以下三个条件:
示例代码:
class Animal {
public:
virtual void speak() {
cout << "Animal speaks" << endl;
}
};
class Dog : public Animal {
public:
void speak() override {
cout << "Dog barks" << endl;
}
};
int main() {
Animal* ptr = new Dog();
ptr->speak(); // 输出: Dog barks
}
虽然指针类型是 Animal*,但调用的是 Dog 的 speak() 函数——这就是运行时多态。
C++编译器为每个含有虚函数的类生成一张虚函数表(vtable),表中存放的是该类所有虚函数的地址。
每个对象内部会自动添加一个隐藏的指针——vptr,它指向所属类的 vtable。
内存布局示意图:
Animal 类:
+------------------+
| vptr --------|-----> [vtable_Animal]
| | +-----------------+
+------------------+ | &Animal::speak |
+-----------------+
Dog 类:
+------------------+
| vptr --------|-----> [vtable_Dog]
| | +---------------+
+------------------+ | &Dog::speak |
+---------------+
当 Dog 重写 speak() 时,它的 vtable 中对应项就指向自己的实现。
当通过基类指针调用虚函数时,实际执行过程如下:
这个过程发生在运行时,因此称为动态绑定。
调用流程图解:
ptr->speak();
- ptr 指向 Dog 对象
- 从 Dog 对象取出 vptr
- vptr 指向 vtable_Dog
- 查找 vtable_Dog 中 speak() 的地址
- 调用 Dog::speak()
理解虚函数机制时需注意:
基本上就这些。虚函数表机制是C++实现面向对象多态的核心,理解它有助于写出更高效、安全的继承代码。