抽象类
来自 cppreference.cn
定义了一个不能被实例化的抽象类型,但可以用作基类。
目录 |
[编辑] 语法
declarator virt-specifier (可选) = 0 |
|||||||||
这里的序列 = 0
被称为 纯说明符,它出现在 声明符 之后或可选的 virt-specifier (override
或 final
) 之后。
pure-specifier 不能出现在成员函数定义或 friend 声明中。
struct Base { virtual int g(); virtual ~Base() {} }; struct A : Base { // OK: declares three member virtual functions, two of them pure virtual int f() = 0, g() override = 0, h(); // OK: destructor can be pure too ~A() = 0; // Error: pure-specifier on a function definition virtual int b() = 0 {} };
抽象类 是一个类,它定义或继承了至少一个函数,该函数的 最终覆盖器 是纯虚函数。
[编辑] 解释
抽象类用于表示一般概念(例如,形状、动物),可以用作具体类(例如,圆形、狗)的基类。
不能创建抽象类的对象(除非是从它派生的类的基类子对象),并且不能声明类型为抽象类的非静态数据成员。
抽象类型不能用作参数类型、函数返回类型或显式转换的类型(请注意,这在定义和函数调用时检查,因为在函数声明点,参数和返回类型可能不完整)。
可以声明指向抽象类的指针和引用。
运行此代码
struct Abstract { virtual void f() = 0; // pure virtual }; // "Abstract" is abstract struct Concrete : Abstract { void f() override {} // non-pure virtual virtual void g(); // non-pure virtual }; // "Concrete" is non-abstract struct Abstract2 : Concrete { void g() override = 0; // pure virtual overrider }; // "Abstract2" is abstract int main() { // Abstract a; // Error: abstract class Concrete b; // OK Abstract& a = b; // OK to reference abstract base a.f(); // virtual dispatch to Concrete::f() // Abstract2 a2; // Error: abstract class (final overrider of g() is pure) }
可以提供纯虚函数的定义(如果纯虚函数是 析构函数,则必须提供):派生类的成员函数可以自由地使用限定函数 ID 调用抽象基类的纯虚函数。此定义必须在类体外部提供(函数声明的语法不允许同时使用纯说明符 = 0
和函数体)。
从抽象类的构造函数或析构函数中对纯虚函数进行虚函数调用是未定义行为(无论它是否有定义)。
struct Abstract { virtual void f() = 0; // pure virtual virtual void g() {} // non-pure virtual ~Abstract() { g(); // OK: calls Abstract::g() // f(); // undefined behavior Abstract::f(); // OK: non-virtual call } }; // definition of the pure virtual function void Abstract::f() { std::cout << "A::f()\n"; } struct Concrete : Abstract { void f() override { Abstract::f(); // OK: calls pure virtual function } void g() override {} ~Concrete() { g(); // OK: calls Concrete::g() f(); // OK: calls Concrete::f() } };
[编辑] 缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
CWG 390 | C++98 | 可能调用未定义的纯虚析构函数 | 在这种情况下需要定义 |
CWG 2153 | C++98 | pure-specifier 可能出现在 friend 声明中 | 禁止 |