代码实现思路
- 定义基类结构体:在基类结构体中定义虚函数,该虚函数将在派生类中被重写。
- 定义派生类结构体:派生类结构体继承自基类结构体,并对基类的虚函数进行重写,以提供不同的行为。
- 使用指针或引用:通过基类指针或引用指向派生类对象,这样在调用虚函数时,会根据对象的实际类型(即运行时类型)来决定调用哪个版本的虚函数,从而实现多态行为。
代码示例
#include <iostream>
// 基类结构体
struct Base {
// 虚函数
virtual void print() const {
std::cout << "This is Base." << std::endl;
}
};
// 派生类结构体
struct Derived : public Base {
// 重写基类的虚函数
void print() const override {
std::cout << "This is Derived." << std::endl;
}
};
int main() {
// 基类指针指向派生类对象
Base* ptr = new Derived();
// 调用虚函数,实际调用的是Derived类的print函数
ptr->print();
// 基类引用指向派生类对象
Derived d;
Base& ref = d;
// 调用虚函数,实际调用的是Derived类的print函数
ref.print();
delete ptr;
return 0;
}
运行时多态性体现原理
- 虚函数表:当一个类包含虚函数时,编译器会为该类生成一个虚函数表(vtable)。虚函数表是一个函数指针数组,每个元素指向类中虚函数的实现。
- 虚函数表指针:每个包含虚函数的类的对象都包含一个指向其类的虚函数表的指针(vptr)。在对象构造时,vptr被初始化,指向该对象所属类的虚函数表。
- 动态绑定:当通过基类指针或引用调用虚函数时,程序在运行时通过对象的vptr找到对应的虚函数表,然后根据虚函数表中函数指针调用实际对象类型(即派生类)的虚函数实现。这就是运行时多态性的原理,它允许根据对象的实际类型来决定调用哪个虚函数版本,而不是根据指针或引用的静态类型。