引言

C++的多态性通过虚函数实现,允许程序在运行时根据对象的实际类型调用相应的函数。本文将深入探讨虚函数、虚析构函数的作用及多态实现机制。

虚函数的作用

虚函数是实现运行时多态的核心机制:

class Base {
public:
    virtual void show() {
        cout << "Base class show function" << endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        cout << "Derived class show function" << endl;
    }
};

调用过程示例

Base* ptr = new Derived();
ptr->show(); // 输出: "Derived class show function"
// 调用过程:通过vptr查找Derived类的vtable,调用Derived::show()

虚析构函数的重要性

防止通过基类指针删除派生类对象时的资源泄漏:

class Base {
public:
    virtual ~Base() = default;
};

class Derived : public Base {
private:
    int* data;
public:
    Derived() : data(new int[100]) {}
    ~Derived() { delete[] data; }
};

调用过程示例

Base* ptr = new Derived();
delete ptr; 
// 调用过程:通过vptr找到Derived的析构函数,先调用~Derived(),再调用~Base()

特殊语法

纯虚函数

class AbstractBase {
public:
    virtual void pureVirtualFunc() = 0; // 纯虚函数
    virtual ~AbstractBase() = default;
};
// 该类不能实例化,必须由派生类实现纯虚函数

= default

virtual ~Base() = default; // 明确要求编译器生成默认析构函数

多态实现机制

虚函数表(V-Table)机制

每个包含虚函数的类都有一个虚函数表,每个对象包含指向该表的指针(vptr)。

完整示例

#include <iostream>
using namespace std;

class Shape {
public:
    virtual double area() const = 0;
    virtual void display() const { cout << "Shape" << endl; }
    virtual ~Shape() = default;
};

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; }
    void display() const override { 
        cout << "Rectangle: " << width << "x" << height << endl; 
    }
};

int main() {
    Shape* shape = new Rectangle(5.0, 3.0);
    
    shape->display();  // 调用过程:通过shape的vptr找到Rectangle的vtable,调用Rectangle::display()
    cout << "Area: " << shape->area() << endl; // 调用Rectangle::area()
    
    delete shape; // 调用过程:通过vptr调用Rectangle析构函数,然后调用Shape析构函数
    
    return 0;
}

关键要点

  1. 虚函数:实现运行时多态,通过vtable机制动态绑定函数
  2. 虚析构函数:确保正确析构派生类对象,防止资源泄漏
  3. 纯虚函数= 0 创建抽象类,强制派生类实现接口
  4. = default:明确要求编译器生成默认实现
  5. 调用过程:对象包含vptr → 查找vtable → 动态调用相应函数

掌握这些机制有助于编写灵活、安全的C++面向对象程序。

更多推荐