C++中的纯虚函数和抽象类是什么?(定义接口规范)

16次阅读

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

C++中的纯虚函数和抽象类是什么?(定义接口规范)

纯虚函数和抽象类不是“定义接口规范”的工具,而是强制派生类实现特定行为的机制。c++ 没有语言级的 Interface 关键字,所以用 = 0 的虚函数配合抽象类来模拟接口语义。

纯虚函数必须写成 virtual 返回类型 函数名() = 0;

它只声明不提供实现,语法上必须带 = 0,且只能出现在类定义内部。注意:

  • = 0 不代表返回值为 0,只是标记该函数为纯虚
  • 含纯虚函数的类不能实例化,哪怕其他所有函数都有实现
  • 纯虚函数可以有函数体(定义在类外),但调用仍需通过派生类对象或显式作用域解析,例如 Base::func();
  • 构造函数里不能调用纯虚函数,否则行为未定义;析构函数中调用也极其危险

抽象类是至少含一个纯虚函数的类

它本身不可用 new BaseBase 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,或空实现 };

只要类设计为多态基类(尤其是抽象类),虚析构函数不是可选项,是必需项。漏掉它,运行时几乎不报错,但内存和资源管理会悄悄出问题。

text=ZqhQzanResources