好的,我们来详细解释一下 C++ 中的多态。
多态:面向对象的核心机制
多态(Polymorphism)是面向对象编程(OOP)的三大核心特性之一(封装、继承、多态)。它允许我们使用基类指针或引用来操作派生类对象,并在运行时根据对象的实际类型来调用正确的函数版本。这使得程序更加灵活和可扩展。
核心:运行时绑定(动态绑定)
多态的核心在于动态绑定(Dynamic Binding)或后期绑定(Late Binding)。这与静态绑定(Static Binding)相对。
- 静态绑定: 在编译时就确定了调用哪个函数(根据指针或引用的类型)。
- 动态绑定: 在运行时才确定调用哪个函数(根据指针或引用所指向或引用的实际对象的类型)。
实现机制:虚函数(Virtual Functions)
C++ 通过 虚函数(Virtual Functions) 来实现运行时多态。
class Base {
public:
virtual void show() { // 声明为虚函数
std::cout << "Base::show() called\\n";
}
};
https://weibo.com/tv/show/1034:5274411981537289
https://weibo.com/tv/show/1034:5274411939594253
https://weibo.com/tv/show/1034:5274411901845514
https://weibo.com/tv/show/1034:5274411859640329
https://weibo.com/tv/show/1034:5274411822153752
class Derived : public Base {
public:
void show() override { // 重写基类的虚函数
std::cout << "Derived::show() called\\n";
}
};
https://weibo.com/tv/show/1034:5274411981537289
https://weibo.com/tv/show/1034:5274411939594253
https://weibo.com/tv/show/1034:5274411901845514
https://weibo.com/tv/show/1034:5274411859640329
https://weibo.com/tv/show/1034:5274411822153752
int main() {
Base* basePtr;
Derived derivedObj;
basePtr = &derivedObj; // 基类指针指向派生类对象
basePtr->show(); // 输出: Derived::show() called (多态发生!)
return 0;
}
关键:虚函数表(vtable)
编译器在幕后为每个包含虚函数的类(或从包含虚函数的类派生而来的类)生成一个 虚函数表(Virtual Table, vtable)。每个对象在创建时,内部会包含一个指向其所属类的虚函数表的指针(通常称为 vptr)。
- vtable 结构: 是一个函数指针数组,存储了该类中所有虚函数的地址。
- 派生类 vtable: 派生类的虚函数表继承自基类的虚函数表。
- 如果派生类重写了某个虚函数,则派生类 vtable 中对应的函数指针被更新为指向派生类的函数版本。
- 如果派生类没有重写虚函数,则 vtable 中对应的函数指针仍然指向基类的函数版本。
- 如果派生类定义了新的虚函数,新的函数指针会被添加到 vtable 的末尾。
当通过基类指针或引用调用虚函数时:
这个过程发生在运行时,因此实现了动态绑定。
示例:形状计算
#include <iostream>
#include <vector>
class Shape {
public:
virtual double area() const = 0; // 纯虚函数,Shape成为抽象基类
virtual ~Shape() {} // 基类析构函数通常声明为virtual
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius; // $$ \\pi r^2 $$
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override {
return width * height; // $$ w \\times h $$
}
};
int main() {
std::vector<Shape*> shapes;
shapes.push_back(new Circle(5.0));
shapes.push_back(new Rectangle(4.0, 6.0));
for (Shape* shape : shapes) {
std::cout << "Area: " << shape->area() << std::endl; // 多态调用
}
// 释放内存
for (Shape* shape : shapes) {
delete shape;
}
return 0;
}
输出:
Area: 78.5397
Area: 24
解释:
总结与要点
- 基类中声明虚函数 (virtual)。
- 派生类重写(覆盖)基类的虚函数。
- 通过基类的指针或引用调用虚函数。
理解并熟练运用多态是掌握 C++ 面向对象编程的关键。




