1. 多态的基本概念

多态(Polymorphism)是面向对象编程的核心特性之一,允许同一个接口表现出不同的行为。C++支持两种多态:

  • 编译时多态(静态多态):函数重载、运算符重载、模板
  • 运行时多态(动态多态):虚函数机制

2. 编译时多态

2.1 函数重载

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
};
 
int main() {
    Calculator calc;
    cout << calc.add(1, 2) << endl;        // 调用第一个
    cout << calc.add(1.5, 2.5) << endl;    // 调用第二个
    cout << calc.add(1, 2, 3) << endl;     // 调用第三个
}

2.2 运算符重载

class Complex {
private:
    double real, imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}
    
    // 重载 + 运算符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }
    
    // 重载 << 运算符(友元函数)
    friend ostream& operator<<(ostream& os, const Complex& c) {
        os << c.real << " + " << c.imag << "i";
        return os;
    }
};
 
int main() {
    Complex c1(3, 4), c2(1, 2);
    Complex c3 = c1 + c2;  // 使用重载的+运算符
    cout << c3 << endl;     // 输出: 4 + 6i
}

2.3 模板

template<typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}
 
template<typename T>
class Stack {
private:
    vector<T> elements;
public:
    void push(const T& elem) { elements.push_back(elem); }
    T pop() { 
        T elem = elements.back();
        elements.pop_back();
        return elem;
    }
};

3. 运行时多态(重点)

3.1 虚函数基础

class Animal {
public:
    // 虚函数
    virtual void makeSound() {
        cout << "Animal makes a sound" << endl;
    }
    
    // 普通函数
    void sleep() {
        cout << "Animal is sleeping" << endl;
    }
};
 
class Dog : public Animal {
public:
    // 重写虚函数
    void makeSound() override {
        cout << "Dog barks: Woof!" << endl;
    }
    
    void sleep() {
        cout << "Dog is sleeping" << endl;
    }
};
 
class Cat : public Animal {
public:
    void makeSound() override {
        cout << "Cat meows: Meow!" << endl;
    }
};
 
int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();
    
    // 多态调用(运行时绑定)
    animal1->makeSound();  // 输出: Dog barks: Woof!
    animal2->makeSound();  // 输出: Cat meows: Meow!
    
    // 非多态调用(编译时绑定)
    animal1->sleep();      // 输出: Animal is sleeping
    
    delete animal1;
    delete animal2;
}

3.2 虚函数表(VTable)机制

class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
    void func3() { cout << "Base::func3" << endl; }
};
 
class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
    virtual void func4() { cout << "Derived::func4" << endl; }
};
 
// 内存布局示意:
// Base对象:    [vptr] -> [Base::func1] [Base::func2]
// Derived对象: [vptr] -> [Derived::func1] [Base::func2] [Derived::func4]

虚函数表工作原理:

void demonstrateVTable() {
    Base* ptr = new Derived();
    
    // 调用虚函数时的过程:
    // 1. 通过ptr找到对象
    // 2. 通过对象的vptr找到虚函数表
    // 3. 在虚函数表中找到对应函数的地址
    // 4. 调用该函数
    
    ptr->func1();  // 调用Derived::func1
    ptr->func2();  // 调用Base::func2
    
    delete ptr;
}

4. 纯虚函数和抽象类

4.1 纯虚函数

class Shape {  // 抽象类
public:
    // 纯虚函数
    virtual double area() = 0;
    virtual double perimeter() = 0;
    
    // 抽象类可以有普通成员函数
    void display() {
        cout << "面积: " << area() << endl;
        cout << "周长: " << perimeter() << endl;
    }
};
 
class Rectangle : public Shape {
private:
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    double area() override {
        return width * height;
    }
    
    double perimeter() override {
        return 2 * (width + height);
    }
};
 
class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) : radius(r) {}
    
    double area() override {
        return 3.14159 * radius * radius;
    }
    
    double perimeter() override {
        return 2 * 3.14159 * radius;
    }
};

4.2 接口类(Interface)

// C++中的接口通常用纯虚函数实现
class IDrawable {
public:
    virtual ~IDrawable() = default;
    virtual void draw() = 0;
    virtual void setColor(string color) = 0;
};
 
class IResizable {
public:
    virtual ~IResizable() = default;
    virtual void resize(double factor) = 0;
};
 
// 多重继承实现多个接口
class Widget : public IDrawable, public IResizable {
private:
    string color;
    double size;
public:
    void draw() override {
        cout << "Drawing widget with color: " << color << endl;
    }
    
    void setColor(string c) override {
        color = c;
    }
    
    void resize(double factor) override {
        size *= factor;
    }
};

5. 虚析构函数

5.1 为什么需要虚析构函数

class Base {
public:
    Base() { cout << "Base构造" << endl; }
    ~Base() { cout << "Base析构" << endl; }  // 非虚析构函数
};
 
class Derived : public Base {
private:
    int* data;
public:
    Derived() : data(new int[100]) { 
        cout << "Derived构造" << endl; 
    }
    ~Derived() { 
        delete[] data;
        cout << "Derived析构" << endl; 
    }
};
 
int main() {
    Base* ptr = new Derived();
    delete ptr;  // 问题:只调用Base析构函数,内存泄漏!
}

5.2 解决方案

class Base {
public:
    Base() { cout << "Base构造" << endl; }
    virtual ~Base() { cout << "Base析构" << endl; }  // 虚析构函数
};
 
// 现在delete ptr会正确调用Derived的析构函数

6. 高级多态应用

6.1 工厂模式

class Product {
public:
    virtual ~Product() = default;
    virtual void use() = 0;
};
 
class ConcreteProductA : public Product {
public:
    void use() override {
        cout << "Using Product A" << endl;
    }
};
 
class ConcreteProductB : public Product {
public:
    void use() override {
        cout << "Using Product B" << endl;
    }
};
 
class Factory {
public:
    static unique_ptr<Product> createProduct(string type) {
        if (type == "A") {
            return make_unique<ConcreteProductA>();
        } else if (type == "B") {
            return make_unique<ConcreteProductB>();
        }
        return nullptr;
    }
};

6.2 策略模式

class SortStrategy {
public:
    virtual ~SortStrategy() = default;
    virtual void sort(vector<int>& data) = 0;
};
 
class BubbleSort : public SortStrategy {
public:
    void sort(vector<int>& data) override {
        cout << "使用冒泡排序" << endl;
        // 实现冒泡排序
    }
};
 
class QuickSort : public SortStrategy {
public:
    void sort(vector<int>& data) override {
        cout << "使用快速排序" << endl;
        // 实现快速排序
    }
};
 
class Sorter {
private:
    unique_ptr<SortStrategy> strategy;
public:
    void setStrategy(unique_ptr<SortStrategy> s) {
        strategy = move(s);
    }
    
    void performSort(vector<int>& data) {
        if (strategy) {
            strategy->sort(data);
        }
    }
};

7. 完整示例:游戏角色系统

#include <iostream>
#include <vector>
#include <memory>
#include <string>
using namespace std;
 
// 技能接口
class ISkill {
public:
    virtual ~ISkill() = default;
    virtual void execute() = 0;
    virtual int getDamage() = 0;
};
 
// 具体技能
class FireballSkill : public ISkill {
public:
    void execute() override {
        cout << "发射火球!造成" << getDamage() << "点伤害" << endl;
    }
    int getDamage() override { return 50; }
};
 
class LightningSkill : public ISkill {
public:
    void execute() override {
        cout << "释放闪电!造成" << getDamage() << "点伤害" << endl;
    }
    int getDamage() override { return 75; }
};
 
// 角色基类
class Character {
protected:
    string name;
    int health;
    int mana;
    vector<unique_ptr<ISkill>> skills;
    
public:
    Character(string n, int h, int m) 
        : name(n), health(h), mana(m) {}
    
    virtual ~Character() = default;
    
    // 纯虚函数
    virtual void attack() = 0;
    virtual void defend() = 0;
    
    // 虚函数
    virtual void display() {
        cout << name << " - HP: " << health << ", MP: " << mana << endl;
    }
    
    void addSkill(unique_ptr<ISkill> skill) {
        skills.push_back(move(skill));
    }
    
    void useSkill(int index) {
        if (index >= 0 && index < skills.size()) {
            skills[index]->execute();
        }
    }
};
 
// 战士类
class Warrior : public Character {
private:
    int armor;
public:
    Warrior(string n) : Character(n, 150, 50), armor(30) {}
    
    void attack() override {
        cout << name << " 挥舞巨剑攻击!" << endl;
    }
    
    void defend() override {
        cout << name << " 举盾防御!护甲值: " << armor << endl;
    }
    
    void display() override {
        Character::display();
        cout << "职业: 战士, 护甲: " << armor << endl;
    }
};
 
// 法师类
class Mage : public Character {
private:
    int spellPower;
public:
    Mage(string n) : Character(n, 80, 150), spellPower(50) {}
    
    void attack() override {
        cout << name << " 施放魔法攻击!法术强度: " << spellPower << endl;
    }
    
    void defend() override {
        cout << name << " 使用魔法护盾!" << endl;
    }
    
    void display() override {
        Character::display();
        cout << "职业: 法师, 法术强度: " << spellPower << endl;
    }
};
 
// 游戏管理器
class GameManager {
private:
    vector<unique_ptr<Character>> characters;
    
public:
    void addCharacter(unique_ptr<Character> character) {
        characters.push_back(move(character));
    }
    
    void showAllCharacters() {
        cout << "\n=== 所有角色 ===" << endl;
        for (const auto& character : characters) {
            character->display();  // 多态调用
            cout << "---" << endl;
        }
    }
    
    void battleDemo() {
        cout << "\n=== 战斗演示 ===" << endl;
        for (const auto& character : characters) {
            character->attack();   // 多态调用
            character->defend();   // 多态调用
            character->useSkill(0);
            cout << endl;
        }
    }
};
 
int main() {
    GameManager game;
    
    // 创建角色
    auto warrior = make_unique<Warrior>("亚瑟");
    warrior->addSkill(make_unique<FireballSkill>());
    
    auto mage = make_unique<Mage>("梅林");
    mage->addSkill(make_unique<LightningSkill>());
    
    // 添加到游戏
    game.addCharacter(move(warrior));
    game.addCharacter(move(mage));
    
    // 展示多态
    game.showAllCharacters();
    game.battleDemo();
    
    return 0;
}

8. 多态的性能考虑

8.1 虚函数开销

  • 空间开销:每个对象多一个vptr指针(通常8字节)
  • 时间开销:间接调用,无法内联优化

8.2 优化建议

// 1. 避免在构造/析构函数中调用虚函数
// 2. 小型频繁调用的函数考虑非虚实现
// 3. 使用final关键字优化
class OptimizedDerived final : public Base {
    void func() override final { }  // 编译器可优化
};

多态是C++实现灵活、可扩展代码的关键特性,合理使用能大大提高代码的可维护性和复用性。