




纯虚函数必须用=0声明且无函数体,含纯虚函数的类为抽象类不可实例化;析构函数可纯虚但须定义;接口类需虚析构、禁拷贝、无数据成员。
= 0 声明,且不能有函数体纯虚函数本质是强制派生类实现的接口契约,语法上只允许声明、不允许定义。一旦在类中声明了纯虚函数,该类就自动成为抽象类,无法实例化。
常见错误是误写成 virtual void func() = 0 {} 或 virtual void func() = 0; 后又在类外定义 void Base::func() { }——这两者都会导致编译失败

= 0 必须紧贴函数声明末尾,中间不能有空格或注释抽象类不是“全纯虚”的接口容器,它完全可以封装共用逻辑。比如网络模块的 Connection 抽象基类,可能有纯虚的 connect() 和 send(),但共用的重连逻辑、超时计时器管理、日志前缀生成等,都可作为 protected 的普通成员函数存在。
关键判断标准不是“有没有非纯虚函数”,而是“是否存在至少一个纯虚函数”——只要有一个,就不能 new 实例。
virtual bool start() = 0;)virtual void on_error() { log("default error handler"); })void validate_config() const;)C++ 标准不支持 Java 那种 interface 语法,所谓“接口类”就是所有函数都是 public 纯虚、无数据成员、无构造/析构逻辑的抽象类。但它不是语言层面的独立概念,只是约定俗成的设计模式。
典型接口类写法:class ILogger { public: virtual ~ILogger() = default; virtual void log(const char* msg) = 0; };。注意两点:析构函数必须是虚的(通常设为 = default),且推荐显式加 public:,避免误用 private 继承破坏多态。
ILogger(const ILogger&) = delete;
如果子类继承抽象基类但没重写全部纯虚函数,它自己仍是抽象类;只有当所有纯虚函数都被实现(且非 inline 定义在类内时需确保链接可见),才能实例化。
容易忽略的是:纯虚函数在派生类中重写时,override 关键字不是必须的,但强烈建议加上。它能防止签名不一致(比如参数类型差一个 const)导致的静默失败——编译器会报错,而不是让你以为已实现。
undefined reference to 'Base::pure_func()'
error: cannot declare variable 'x' to be of abstract type 'Derived'
抽象类的核心约束不在语法多严格,而在设计意图是否清晰:哪些必须由用户定制,哪些可以复用,哪些绝对不能碰。把纯虚函数当成 API 边界来画,比纠结“是不是够纯”更有实际意义。