c++中“接口类”是纯抽象类:所有成员函数均为public virtual纯虚函数,无数据成员和构造函数实现,仅定义行为契约;必须含虚析构函数,推荐使用= default,且所有函数应加const限定以确保正确重写。

什么是C++里的“接口类”
C++没有interface关键字,所谓“接口类”是开发者约定的纯抽象类:所有成员函数都是public、virtual、且声明为= 0,不含数据成员和构造函数实现。它不提供任何具体行为,只定义契约。
- 必须至少有一个纯虚函数,否则不是抽象类
- 析构函数也应声明为
virtual,否则通过基类指针删除派生对象时会未定义行为 - 不需要
virtual修饰纯虚函数的首次声明(但显式写上更清晰) - 接口类通常不定义构造函数,或只提供
protected默认构造函数以防被直接实例化
如何正确定义一个接口类
关键不是“怎么写”,而是“怎么避免误用”。下面是最小安全模板:
class IShape {
public:
virtual ~IShape() = default; // 必须有虚析构
virtual double area() const = 0;
virtual void draw() const = 0;
};
-
IShape前缀是常见命名习惯,非强制,但能一眼区分接口与具体类 - 所有函数加
const(如果逻辑上不修改状态),否则实现类可能因const限定无法重写 - 不写
virtual在派生类重写中不会报错,但若未来该类被多层继承,缺少virtual可能导致意外的静态绑定 - 避免在接口中使用非虚函数、静态成员、友元或模板成员——它们破坏了纯粹的契约语义
为什么不能有数据成员或非纯虚函数
这不是语法限制,而是设计意图的崩塌点:
- 出现
int id;会让实现类被迫继承该字段,违反“只定义行为”的原则 - 加一个非纯虚函数(比如
log_name())意味着接口开始掺杂默认实现,它就不再是接口,而成了抽象基类(abstract base class),容易误导调用方预期 - 若接口类含
static成员,多个实现类共享同一份数据,会导致隐式耦合,违背松耦合目标 - 派生类若忘记重写某个纯虚函数,编译器会直接报错;但若接口里混入非纯虚函数,错误会延迟到运行时或逻辑异常才暴露
实际使用时最容易漏掉的两件事
- 忘记给析构函数加
virtual,尤其当接口用于工厂函数返回std::unique_ptr<ishape></ishape>时,delete会跳过派生类析构体
- 在头文件中定义接口后,没把
virtual析构写成= default或{},导致链接时报undefined reference to 'vtable for IShape'
virtual,尤其当接口用于工厂函数返回std::unique_ptr<ishape></ishape>时,delete会跳过派生类析构体 virtual析构写成= default或{},导致链接时报undefined reference to 'vtable for IShape' 前者让资源泄漏静默发生,后者让编译卡在链接阶段,查起来反而比语法错误更费时间。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











