抽象类因含纯虚函数而无法实例化,这是C++标准规定的编译期硬性约束;其派生类若未实现全部纯虚函数仍为抽象类,但可定义构造函数、成员变量及普通函数,并支持指针/引用的模板推导等高级用法。

因为抽象类中至少有一个未实现的纯虚函数,C++标准明确禁止实例化——这不是编译器“懒得支持”,而是语义层面的硬性约束。
抽象类的实例化尝试会触发编译错误
只要类中声明了 virtual void func() = 0;,哪怕其他所有函数都已实现,AbstractClass obj; 这行代码就会被编译器直接拒绝。
常见错误信息类似:error: cannot declare variable 'obj' to be of abstract type 'AbstractClass'。注意,这是编译期错误,不是运行时崩溃。
原因很直接:对象构造需要为每个虚函数表(vtable)项填入有效函数地址;而纯虚函数在抽象类中没有地址可填,vtable 留空即违法。
立即学习“C++免费学习笔记(深入)”;
派生类没实现全部纯虚函数,照样不能实例化
抽象类的“传染性”容易被低估。如果派生类只重写了部分纯虚函数,它自己仍是抽象类。
class Shape { virtual double area() const = 0; virtual void draw() const = 0; };-
class Circle : public Shape { double area() const override { return 3.14 * r * r; } };→Circle仍含未实现的draw(),无法实例化 - 必须全部实现,或显式用
= 0声明新纯虚函数来延续抽象性
抽象类可以有构造函数、成员变量和普通函数
不能实例化 ≠ 不能定义任何东西。抽象类完全可以:
- 声明
protected构造函数(常用于防止误用) - 持有数据成员(如
std::string name;) - 提供已实现的普通成员函数(如
void print_info() { std::cout ) - 声明虚析构函数(
virtual ~Shape() = default;必须!否则通过基类指针 delete 派生类对象会未定义行为)
这些都不影响其抽象性,但能显著提升派生类复用效率。
指向抽象类的指针和引用是合法且常用的
虽然不能 Shape s;,但 Shape* p = new Circle; 或 const Shape& ref = some_circle; 完全没问题——这才是抽象类的设计本意。
多态调用依赖的就是这种间接访问方式。一旦你写 p->area(),实际执行的是 Circle::area(),前提是该函数已被正确 override 且非 final。
容易忽略的一点:抽象类的虚函数表虽不完整,但它的指针/引用类型本身是完整类型(complete type),所以能参与模板推导、作为容器元素类型(如 std::vector<:unique_ptr>></:unique_ptr>)等高级用法。


















