抽象类因含纯虚函数(= 0)而无法实例化,此为编译期强制检查;派生类须显式实现所有继承的纯虚函数且签名一致,才成为具体类。

抽象类不能直接实例化,编译器会报错 error: cannot declare variable 'x' to be of abstract type
抽象类只要包含至少一个 pure virtual function(纯虚函数),就失去构造具体对象的能力。这不是运行时限制,而是编译期强制检查——哪怕纯虚函数有实现体,只要声明为 = 0,该类就不可实例化。
常见错误场景:
- 误写
Base obj;,其中Base含virtual void f() = 0; - 试图用
new Base创建堆对象,同样失败 - 派生类未重写全部纯虚函数,仍属抽象类,也无法实例化
纯虚函数定义本身不阻止派生类实例化,但继承链必须“补全”所有纯虚接口
派生类只有在**显式提供所有继承来的纯虚函数的非纯虚实现**后,才成为具体类(concrete class)。注意:重写必须是 public 且签名完全一致(返回类型协变除外)。
实操要点:
立即学习“C++免费学习笔记(深入)”;
- 派生类中用
override显式标注,避免因拼写/const/volatile 不匹配导致隐式继承纯虚性 - 基类纯虚函数有默认实现(如
virtual void log() = 0 { std::cout ),不影响抽象性,也不免除派生类实现义务 - 多重继承时,每个父类的纯虚函数都需覆盖,缺一不可
想绕过限制?只能通过指针或引用操作抽象类对象,且目标必须是具体派生类
抽象类的真正用途是作为接口规范,实际对象必须由子类创建。典型模式:
Base* p = new Derived(); // OK:指向具体对象 Base& r = *p; // OK:绑定到具体对象 Base b; // ERROR:禁止
关键点:
-
new Derived()成立的前提是Derived已实现全部纯虚函数 - 不能对抽象类使用
std::make_unique或() std::shared_ptr(new Base) - 若用模板工厂(如
create),模板实参必须是具体类型()
例外情况:抽象类的纯虚析构函数可以有实现,且不影响实例化规则
如果只为支持多态删除而声明纯虚析构函数(virtual ~Base() = 0;),**必须提供定义体**,否则链接失败。但这不改变抽象性——该类依然不可实例化。
正确写法:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {} // 必须定义,哪怕为空
容易踩的坑:
- 只声明
= 0而不定义,链接时报undefined reference to 'Base::~Base()' - 误以为加了析构实现就“解除抽象”,其实只要还有别的纯虚函数,仍不能实例化
抽象类的核心约束始终落在“是否所有纯虚函数都被覆盖”上,而不是有没有构造函数、有没有数据成员,或者析构函数怎么写。最常被忽略的是:即使只漏写一个 override,整个继承链就卡在抽象层动不了。










