多态指同一接口在不同对象中表现不同行为,分为编译时多态(函数重载)和运行时多态(虚函数),核心通过虚函数表实现动态绑定,需继承、virtual声明、重写及基类指针调用,抽象类含纯虚函数不可实例化,提升代码扩展性。

在C++中,多态是指同一接口在不同对象上表现出不同的行为。它允许我们用统一的方式处理不同类型的对象,是面向对象编程的三大核心特性之一(封装、继承、多态)。多态提高了代码的可扩展性和可维护性。
多态的基本概念
多态分为两种:编译时多态和运行时多态。
- 编译时多态:通过函数重载和运算符重载实现,在编译阶段就确定调用哪个函数。
- 运行时多态:通过虚函数和继承实现,在程序运行时根据对象的实际类型决定调用哪个函数。
通常所说的“C++多态”指的是运行时多态,它是通过基类指针或引用调用虚函数时,实际执行的是派生类中的函数版本。
多态的实现原理:虚函数与虚表
运行时多态的核心机制是虚函数(virtual function)和虚函数表(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
delete ptr;
return 0;
}
虽然指针类型是 Animal*,但调用的是 Dog 的 speak() 函数,这就是多态的体现。
实现多态的关键条件
- 必须有继承关系。
- 基类中的函数必须声明为 virtual。
- 派生类重写(override)基类的虚函数。
- 通过基类的指针或引用调用虚函数。
注意:普通成员函数调用是静态绑定(编译时决定),而虚函数调用是动态绑定(运行时决定)。
纯虚函数与抽象类
有时我们希望基类只定义接口而不提供实现,这时可以使用纯虚函数:
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a circle" << endl;
}
};
包含纯虚函数的类称为抽象类,不能实例化对象。派生类必须实现所有纯虚函数,否则仍是抽象类。
基本上就这些。多态让代码更灵活,能适应未来扩展,比如新增一个图形类无需修改已有调用逻辑。理解虚表机制有助于掌握底层原理,写出更高效的代码。











