17370845950

C++如何通过虚函数实现多态?(代码示例)
虚函数是C++实现运行时多态的核心机制:基类用virtual声明,派生类用override重写,通过基类指针或引用调用时动态绑定到派生类版本;虚析构函数防止内存泄漏;纯虚函数(=0)使类成为抽象类,强制派生类实现。

虚函数是C++实现运行时多态的核心机制:基类中声明virtual函数,派生类重写该函数,通过基类指针或引用调用时,实际执行的是派生类的版本。

虚函数的基本写法

在基类中用virtual关键字声明函数,派生类中用override(推荐)显式表明重写,编译器会检查签名是否匹配。

示例:

class Shape {
public:
    virtual double area() const { return 0; } // 虚函数
    virtual ~Shape() = default; // 虚析构函数很重要
};

class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) {} double area() const override { return 3.1416 radius radius; } };

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; } };

通过基类指针/引用调用实现多态

只有通过基类的指针或引用调用虚函数,才能触发动态绑定;直接用对象调用仍是静态绑定(即不发生多态)。

  • ✅ 正确(多态生效):Shape* p = new Circle(5); p->area();
  • ❌ 无效(无多态):Circle c(5); c.area(); —— 这只是普通函数调用

虚析构函数为什么必须?

如果基类析构函数不是虚函数,用Shape* ptr = new Circle;创建对象后,delete ptr;只会调用Shape

::~Shape(),导致派生类部分内存泄漏。

加上virtual ~Shape() = default;后,delete ptr会正确调用Circle::~Circle()再调用基类析构函数。

纯虚函数与抽象类

将虚函数声明为= 0,就变成纯虚函数;含纯虚函数的类不可实例化,称为抽象类,强制派生类实现该接口。

例如:

class Shape {
public:
    virtual double area() const = 0; // 纯虚函数
    virtual ~Shape() = default;
}; // Shape 现在是抽象类,不能定义 Shape obj;