virtual void xxx();---->虚函数

class Base {
public:
    virtual void show(); // 虚函数
};

class Derived : public Base {
public:
    void show() override; // 覆盖虚函数
};

🧠虚函数表(vtable)机制

每个含虚函数的类都有一张虚表,指向该类的全部虚函数实现。
每个对象有一个虚表指针(vptr),初始化在构造函数中。
动态绑定就是通过虚表指针查找最终函数地址。

类A对象的存储空间以及虚函数表

🧠注意事项与易错点

易错点 说明
构造函数不能是虚函数 构造时虚表尚未建立,不支持虚调用
析构函数建议定义为虚函数 避免用基类指针删除派生类对象时资源泄漏
覆盖函数应加 override 关键字 编译器校验防止写错函数签名
虚函数可以有默认参数,但默认值根据静态类型确定 和调用版本分离

virtual void xxx()=0;---->纯虚函数

class Shape {
public:
    virtual void draw() = 0; // 纯虚函数
};
Shape* p = new Circle(); // 多态调用 draw()

🧠纯虚函数标准语法

【1】使用virtual关键字
【2】函数声明后加上“=0”
【3】明确返回值类型

🧠注意事项与易错点

1、纯虚函数可以使用指针和引用,纯虚函数通常通过基类指针或引用调用派生类中的具体实现

2、包含纯虚函数的类是一个抽象类,不能直接实例化对象,抽象类只能作为基类使用当作指针/引用,必须由派生类实现所有纯虚函数后才能创建对象

3、末尾“=0”只是一个语法标记,表示这个是一个纯虚函数,与函数的返回值无关,就是形式上的作用

4、虚函数和纯虚函数都可以在子类中重载以多态的形式被调用

总结

项目 虚函数(virtual) 纯虚函数(pure virtual)
定义方式 virtual void f(); virtual void f() = 0;
实现是否必须? 可以实现,也可以不实现 必须由子类实现(否则子类仍是抽象类)
是否可实例化? 类可以实例化 类不能实例化(抽象类)
用途 支持多态(虚函数机制) 规范接口(面向接口编程)