纯虚函数是强制派生类实现特定行为的机制,语法为virtual 返回类型 函数名() = 0;含纯虚函数的抽象类不可实例化,但可作指针或引用类型,且必须声明虚析构函数以防资源泄漏。

纯虚函数和抽象类不是“定义接口规范”的工具,而是强制派生类实现特定行为的机制。C++ 没有语言级的 interface 关键字,所以用 = 0 的虚函数配合抽象类来模拟接口语义。
纯虚函数必须写成 virtual 返回类型 函数名() = 0;
它只声明不提供实现,语法上必须带 = 0,且只能出现在类定义内部。注意:
-
= 0不代表返回值为 0,只是标记该函数为纯虚 - 含纯虚函数的类不能实例化,哪怕其他所有函数都有实现
- 纯虚函数可以有函数体(定义在类外),但调用仍需通过派生类对象或显式作用域解析,例如
Base::func(); - 构造函数里不能调用纯虚函数,否则行为未定义;析构函数中调用也极其危险
抽象类是至少含一个纯虚函数的类
它本身不可用 new Base 或 Base obj; 创建对象,但可作为指针或引用类型使用:
class Shape {
public:
virtual double area() const = 0; // 纯虚
virtual ~Shape() = default; // 抽象类建议有虚析构
};
class Circle : public Shape {
double r;
public:
Circle(double r) : r(r) {}
double area() const override { return 3.14159 r r; }
};
Shape* s = new Circle(2.0); // ✅ 合法:指向派生类对象
// Shape s2; // ❌ 编译错误:无法实例化抽象类
抽象类 ≠ Java/C# 的 interface
C++ 抽象类可以包含数据成员、非虚函数、静态成员、甚至带实现的虚函数,而不仅仅是“纯接口”:
立即学习“C++免费学习笔记(深入)”;
- 想模拟纯接口?那就把所有成员函数都设为
public virtual ... = 0,且不加数据成员 - 想提供默认行为?可以在基类中给某些虚函数写实现,派生类可选择是否
override - 多继承时,多个抽象基类组合很常见,但要注意菱形继承和
virtual继承的必要性 - 没有
final修饰符限制继承时,任何派生类都可能继续被继承——这点常被忽略
容易踩的坑:析构函数没设为虚
如果通过 Shape* 删除 Circle 对象,而 Shape::~Shape() 不是虚函数,派生类析构函数不会被调用,造成资源泄漏:
class Shape {
public:
virtual double area() const = 0;
// ❌ 缺少 virtual ~Shape() → 行为未定义
};
// ✅ 正确写法:
class Shape {
public:
virtual double area() const = 0;
virtual ~Shape() = default; // 或 = default,或空实现
};
只要类设计为多态基类(尤其是抽象类),虚析构函数不是可选项,是必需项。漏掉它,运行时几乎不报错,但内存和资源管理会悄悄出问题。










