C++面向对象编程三大特性之一:多态
面向对象编程的精华,让代码拥有灵活性的魔法
1. 多态的基本概念
1.1 什么是多态?
多态(Polymorphism)是面向对象编程的三大核心特性之一(另外两个是封装和继承),字面意思是"多种形态"。在编程领域,
多态指的是同一接口可以根据不同情况表现出不同行为
的特性。简单来说,多态允许我们使用相同的接口来操作不同的数据类型,从而产生不同的行为结果。就像现实生活中的"开车"这个行为,无论是开轿车、卡车还是公交车,基本操作接口(方向盘、油门、刹车)是相似的,但具体执行效果却因车辆类型而异。
1.2 多态的分类
C++中的多态主要分为两大类:
类型 | 实现方式 | 确定时机 | 特点 |
---|---|---|---|
编译时多态(静态多态) | 函数重载、模板 | 编译期间 | 性能高,缺乏灵活性 |
运行时多态(动态多态) | 虚函数、继承 | 运行期间 | 灵活性强,有轻微性能开销 |
编译时多态
主要通过函数重载和模板实现,编译器在编译阶段就能确定要调用哪个函数版本。
运行时多态
则通过虚函数和继承机制实现,具体调用哪个函数要在程序运行时才能确定。
2. 多态的实现机制
2.1 运行时多态的实现条件
要实现运行时多态,必须同时满足以下三个条件:
- 继承关系:存在基类和派生类的继承层次
- 虚函数重写:派生类重写基类中的虚函数
- 基类指针/引用:通过基类指针或引用调用虚函数
#include <iostream>
using namespace std;// 基类class Animal {
public:virtual void speak() {// 虚函数cout << "Animal speaks" << endl;}
};// 派生类class Dog : public Animal {
public:void speak() override {// 重写基类虚函数cout << "Dog barks" << endl;}
};class Cat : public Animal {
public:void speak() override {cout << "Cat meows" << endl;}
};int main() {Animal* animal1 = new Dog();// 基类指针指向派生类对象Animal* animal2 = new Cat();animal1->speak();// 输出: Dog barksanimal2->speak();// 输出: Cat meowsdelete animal1;delete animal2;return 0;
}
2.2 虚函数的关键要点
虚函数声明:在成员函数前加上virtual
关键字即可声明为虚函数:
class Base {
public:virtual void show() {// 虚函数cout << "Base class" << endl;}
};
override关键字:C++11引入override
关键字,显式表明函数重写基类虚函数,让编译器检查重写的正确性:
class Derived : public Base {
public:void show() override {// 明确表示重写基类虚函数cout << "Derived class" << endl;}
};
final关键字:阻止派生类重写虚函数:
class Base {
public:virtual void show() final {// 禁止派生类重写此函数cout << "Base class" << endl;}
};
3. 多态的原理剖析
3.1 虚函数表(vtable)机制
C++通过虚函数表来实现运行时多态。每个包含虚函数的类都有一个虚函数表,其中存储了该类所有虚函数的地址。每个对象内部包含一个指向虚函数表的指针(vptr)。
当通过基类指针调用虚函数时,程序会执行以下步骤:
- 通过对象的vptr找到对应的虚函数表
- 在虚函数表中查找要调用的函数地址
- 调用该地址指向的函数
class Base {
public:virtual void func1() { cout << "Base::func1" << endl; }virtual void func2() { cout << "Base::func2" << endl;