面向对象的编程:多态
C++ 多态详解
多态是面向对象编程的三大核心特性之一(封装、继承、多态),它允许使用统一的接口处理不同类型的对象,实现"一个接口,多种实现"的效果。
多态的类型
C++ 中主要支持两种多态:
-
编译时多态(静态多态)
- 通过函数重载和模板实现
- 在编译时确定调用哪个函数
-
运行时多态(动态多态)
- 通过虚函数和继承实现
- 在运行时确定调用哪个函数
运行时多态的实现机制
运行时多态主要通过以下机制实现:
-
虚函数 (virtual function)
- 在基类中使用
virtual
关键字声明 - 派生类可以重写 (override) 虚函数
- 在基类中使用
-
虚函数表 (vtable)
- 每个包含虚函数的类都有一个虚函数表
- 表中存储了指向实际函数的指针
- 对象中包含指向虚函数表的指针 (vptr)
-
动态绑定
- 通过基类指针或引用调用虚函数时
- 根据实际对象类型决定调用哪个函数
多态的基本语法
class Shape {
public:
virtual void draw() { // 虚函数
cout << "Drawing a shape" << endl;
}
virtual ~Shape() {} // 虚析构函数
};
class Circle : public Shape {
public:
void draw() override { // 重写虚函数
cout << "Drawing a circle" << endl;
}
};
class Square : public Shape {
public:
void draw() override {
cout << "Drawing a square" << endl;
}
};
void drawShape(Shape& shape) {
shape.draw(); // 多态调用
}
int main() {
Circle circle;
Square square;
drawShape(circle); // 输出: Drawing a circle
drawShape(square); // 输出: Drawing a square
return 0;
}
多态的关键特性
-
override 关键字
- C++11 引入,明确表示重写虚函数
- 帮助编译器检查是否正确重写
-
final 关键字
- 防止函数被进一步重写
- 防止类被继承
-
纯虚函数和抽象类
- 纯虚函数:
virtual void func() = 0;
- 包含纯虚函数的类是抽象类
- 不能实例化抽象类
- 纯虚函数:
-
虚析构函数
- 基类析构函数应该声明为虚函数
- 确保通过基类指针删除派生类对象时正确调用析构函数
多态的实际应用示例
#include <iostream>
#include <vector>
using namespace std;
// 抽象基类
class Employee {
public:
virtual void calculateSalary() = 0; // 纯虚函数
virtual ~Employee() {}
};
class FullTimeEmployee : public Employee {
private:
double monthlySalary;
public:
FullTimeEmployee(double salary) : monthlySalary(salary) {}
void calculateSalary() override {
cout << "Full-time employee salary: " << monthlySalary << endl;
}
};
class PartTimeEmployee : public Employee {
private:
double hourlyRate;
int hoursWorked;
public:
PartTimeEmployee(double rate, int hours)
: hourlyRate(rate), hoursWorked(hours) {}
void calculateSalary() override {
cout << "Part-time employee salary: "
<< hourlyRate * hoursWorked << endl;
}
};
int main() {
vector<Employee*> employees;
employees.push_back(new FullTimeEmployee(5000));
employees.push_back(new PartTimeEmployee(20, 80));
for (auto emp : employees) {
emp->calculateSalary(); // 多态调用
delete emp;
}
return 0;
}
多态的优势
- 代码可扩展性:添加新类不影响现有代码
- 接口统一:通过基类接口操作不同派生类对象
- 可维护性:减少条件判断语句
- 灵活性:运行时决定对象行为
多态的最佳实践
- 基类析构函数应该声明为虚函数
- 使用 override 关键字明确表示重写
- 合理使用抽象类和纯虚函数定义接口
- 避免在构造函数和析构函数中调用虚函数
- 考虑使用智能指针管理多态对象
多态是C++面向对象编程中最强大的特性之一,合理使用可以创建灵活、可扩展的系统架构。