118 lines
5.2 KiB
Markdown
118 lines
5.2 KiB
Markdown
[class.abstract]
|
||
|
||
# 11 Classes [[class]](./#class)
|
||
|
||
## 11.7 Derived classes [[class.derived]](class.derived#class.abstract)
|
||
|
||
### 11.7.4 Abstract classes [class.abstract]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4199)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
The abstract class mechanism supports the notion of a general concept,
|
||
such as a shape, of which only more concrete variants, such ascircle and square, can actually be used[.](#1.sentence-1)
|
||
|
||
An abstract
|
||
class can also be used to define an interface for which derived classes
|
||
provide a variety of implementations[.](#1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4208)
|
||
|
||
A virtual function is specified as
|
||
a [*pure virtual function*](#def:function,virtual,pure "11.7.4 Abstract classes [class.abstract]") by using a[*pure-specifier*](class.mem.general#nt:pure-specifier "11.4.1 General [class.mem.general]") ([[class.mem]](class.mem "11.4 Class members")) in the function declaration
|
||
in the class definition[.](#2.sentence-1)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
Such a function might be inherited: see below[.](#2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
A class is an [*abstract class*](#def:class,abstract "11.7.4 Abstract classes [class.abstract]") if it has at least one pure virtual function[.](#2.sentence-3)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
An abstract class can be used only as a base class of some other class;
|
||
no objects of an abstract class can be created
|
||
except as subobjects of a class
|
||
derived from it ([[basic.def]](basic.def "6.2 Declarations and definitions"), [[class.mem]](class.mem "11.4 Class members"))[.](#2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
A pure virtual function need be defined only if called with, or as if
|
||
with ([[class.dtor]](class.dtor "11.4.7 Destructors")), the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") syntax ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))[.](#2.sentence-5)
|
||
|
||
[*Example [1](#example-1)*: class point { /* ... */ };class shape { // abstract class point center;public: point where() { return center; }void move(point p) { center=p; draw(); }virtual void rotate(int) = 0; // pure virtualvirtual void draw() = 0; // pure virtual}; â *end example*]
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
A function declaration cannot provide both a [*pure-specifier*](class.mem.general#nt:pure-specifier "11.4.1 General [class.mem.general]") and a definition[.](#2.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#example-2)*: struct C {virtual void f() = 0 { }; // error}; â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4253)
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
An abstract class type cannot be used
|
||
as a parameter or return type of
|
||
a function being defined ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) or called ([[expr.call]](expr.call "7.6.1.3 Function call")),
|
||
except as specified in [[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers")[.](#3.sentence-1)
|
||
|
||
Further, an abstract class type cannot be used as
|
||
the type of an explicit type conversion ([[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.reinterpret.cast]](expr.reinterpret.cast "7.6.1.10 Reinterpret cast"), [[expr.const.cast]](expr.const.cast "7.6.1.11 Const cast")),
|
||
because the resulting prvalue would be of abstract class type ([[basic.lval]](basic.lval "7.2.1 Value category"))[.](#3.sentence-2)
|
||
|
||
However, pointers and references to abstract class types
|
||
can appear in such contexts[.](#3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4267)
|
||
|
||
A class is abstract if it has at least one pure virtual
|
||
function for which the final overrider is pure virtual[.](#4.sentence-1)
|
||
|
||
[*Example [3](#example-3)*: class ab_circle : public shape {int radius;public:void rotate(int) { }// ab_circle::draw() is a pure virtual};
|
||
|
||
Since shape::draw() is a pure virtual functionab_circle::draw() is a pure virtual by default[.](#4.sentence-2)
|
||
|
||
The alternative
|
||
declaration,class circle : public shape {int radius;public:void rotate(int) { }void draw(); // a definition is required somewhere}; would make class circle non-abstract and a definition ofcircle::draw() must be provided[.](#4.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4296)
|
||
|
||
[*Note [6](#note-6)*:
|
||
|
||
An abstract class can be derived from a class that is not abstract, and
|
||
a pure virtual function can override a virtual function which is not
|
||
pure[.](#5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4303)
|
||
|
||
Member functions can be called from a constructor (or destructor) of an
|
||
abstract class;the effect of making a virtual call ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) to a pure
|
||
virtual function directly or indirectly for the object being created (or
|
||
destroyed) from such a constructor (or destructor) is undefined[.](#6.sentence-1)
|