Abstract class
| General topics | ||||||||||||||||
| Flow control | ||||||||||||||||
| Conditional execution statements | ||||||||||||||||
| Iteration statements (loops) | ||||||||||||||||
|
||||||||||||||||
| Jump statements | ||||||||||||||||
| Functions | ||||||||||||||||
| Function declaration | ||||||||||||||||
| Lambda function expression | ||||||||||||||||
inline
specifier
|
||||||||||||||||
| Dynamic exception specifications ( until C++17* ) | ||||||||||||||||
noexcept
specifier
(C++11)
|
||||||||||||||||
| Exceptions | ||||||||||||||||
| Namespaces | ||||||||||||||||
| Types | ||||||||||||||||
| Specifiers | ||||||||||||||||
|
||||||||||||||||
| Storage duration specifiers | ||||||||||||||||
| Initialization | ||||||||||||||||
| Expressions | ||||||||||||||||
| Alternative representations | ||||||||||||||||
| Literals | ||||||||||||||||
| Boolean - Integer - Floating-point | ||||||||||||||||
| Character - String - nullptr (C++11) | ||||||||||||||||
| User-defined (C++11) | ||||||||||||||||
| Utilities | ||||||||||||||||
| Attributes (C++11) | ||||||||||||||||
| Types | ||||||||||||||||
typedef
declaration
|
||||||||||||||||
| Type alias declaration (C++11) | ||||||||||||||||
| Casts | ||||||||||||||||
| Memory allocation | ||||||||||||||||
| Classes | ||||||||||||||||
| Class-specific function properties | ||||||||||||||||
|
||||||||||||||||
| Special member functions | ||||||||||||||||
|
||||||||||||||||
| Templates | ||||||||||||||||
| Miscellaneous | ||||||||||||||||
| General | ||||
| Overview | ||||
class
/
struct
types
|
||||
union
types
|
||||
| Injected-class-name | ||||
| Class property specifiers (C++26) | ||||
| Members | ||||
| Data members | ||||
| Static members | ||||
The
this
pointer
|
||||
| Nested classes | ||||
| Member templates | ||||
| Bit-fields | ||||
using
-declarations
|
||||
| Member functions | ||||
| Member access specifiers | ||||
| Constructors and member initializer lists | ||||
| Default member initializer (C++11) | ||||
friend
specifier
|
||||
explicit
specifier
|
||||
| Converting constructor | ||||
| Special member functions | ||||
| Default constructor | ||||
| Copy constructor | ||||
| Move constructor (C++11) | ||||
| Copy assignment operator | ||||
| Move assignment operator (C++11) | ||||
| Destructor | ||||
| Inheritance | ||||
| Base and derived classes | ||||
| Empty base optimization (EBO) | ||||
| Virtual member functions | ||||
| Pure virtual functions and abstract classes | ||||
override
specifier
(C++11)
|
||||
final
specifier
(C++11)
|
定义一种抽象类型,该类型无法实例化,但可用作基类。
目录 |
语法
声明符
虚函数说明符
(可选)
=
0
|
|||||||||
此处序列
= 0
被称为
纯说明符
,它紧跟在
声明符
之后出现,或在可选的
虚函数说明符
(
override
或
final
)之后出现。
纯说明符 不能出现在成员函数定义或 友元 声明中。
struct Base { virtual int g(); virtual ~Base() {} }; struct A : Base { // 正确:声明三个成员虚函数,其中两个为纯虚函数 virtual int f() = 0, g() override = 0, h(); // 正确:析构函数也可以声明为纯虚函数 ~A() = 0; // 错误:在函数定义上使用纯说明符 virtual int b() = 0 {} };
一个 抽象类 是指定义或继承至少一个函数的类,其中 最终覆写 为 纯虚函数 。
说明
抽象类用于表示通用概念(例如,Shape、Animal),可作为具体类(例如,Circle、Dog)的基类。
不能创建抽象类的对象(除了从它派生的类的基类子对象),也不能声明类型为抽象类的非静态数据成员。
抽象类型不能用作参数类型、函数返回类型或显式转换的类型(注意这是在定义点和函数调用点检查的,因为在函数声明点参数和返回类型可能不完整)。
可以声明指向抽象类的指针和引用。
struct Abstract { virtual void f() = 0; // 纯虚函数 }; // "Abstract" 是抽象类 struct Concrete : Abstract { void f() override {} // 非纯虚函数 virtual void g(); // 非纯虚函数 }; // "Concrete" 是非抽象类 struct Abstract2 : Concrete { void g() override = 0; // 纯虚函数重写 }; // "Abstract2" 是抽象类 int main() { // Abstract a; // 错误:抽象类 Concrete b; // 正确 Abstract& a = b; // 允许引用抽象基类 a.f(); // 虚函数调用至 Concrete::f() // Abstract2 a2; // 错误:抽象类(g() 的最终重写是纯虚函数) }
纯虚函数的定义可以被提供(且当纯虚函数是
析构函数
时必须提供):派生类的成员函数可以通过限定函数标识符自由调用抽象基类的纯虚函数。此定义必须在类体外部提供(函数声明的语法不允许同时使用纯说明符
= 0
和函数体)。
在抽象类的构造函数或析构函数中对纯虚函数进行虚调用是未定义行为(无论该函数是否具有定义)。
struct Abstract { virtual void f() = 0; // 纯虚函数 virtual void g() {} // 非纯虚函数 ~Abstract() { g(); // 正确:调用 Abstract::g() // f(); // 未定义行为 Abstract::f(); // 正确:非虚调用 } }; // 纯虚函数的定义 void Abstract::f() { std::cout << "A::f()\n"; } struct Concrete : Abstract { void f() override { Abstract::f(); // 正确:调用纯虚函数 } void g() override {} ~Concrete() { g(); // 正确:调用 Concrete::g() f(); // 正确:调用 Concrete::f() } };
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| CWG 390 | C++98 | 未定义的纯虚析构函数可能被调用 | 此情况下需要提供定义 |
| CWG 2153 | C++98 | pure-specifier 可出现在友元声明中 | 已禁止 |