Abstrakte Klasse
Definiert einen abstrakten Typ, der nicht instanziiert werden kann, aber als Basisklasse verwendet werden kann.
Inhalt |
[bearbeiten] Syntax
Eine rein virtuelle Funktion ist eine virtuelle Funktion, deren Deklarator die folgende Syntax aufweist:
Deklarator virt-Spezifizierer (optional) = 0 |
|||||||||
Hier ist die Sequenz = 0 als Rein-Spezifizierer bekannt und erscheint entweder unmittelbar nach dem Deklarator oder nach dem optionalen virt-Spezifizierer (override oder final).
Rein-Spezifizierer kann nicht in einer Member-Funktionsdefinition oder friend Deklaration erscheinen.
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 {} };
Eine abstrakte Klasse ist eine Klasse, die mindestens eine Funktion definiert oder erbt, für die der finale Überschreiber rein virtuell ist.
[bearbeiten] Erklärung
Abstrakte Klassen werden verwendet, um allgemeine Konzepte (z. B. Shape, Animal) darzustellen, die als Basisklassen für konkrete Klassen (z. B. Circle, Dog) verwendet werden können.
Es können keine Objekte einer abstrakten Klasse erstellt werden (außer Basis-Subobjekte einer von ihr abgeleiteten Klasse) und es können keine nicht-statischen Datenmember deklariert werden, deren Typ eine abstrakte Klasse ist.
Abstrakte Typen können nicht als Parametertypen, als Rückgabetypen von Funktionen oder als Typ einer expliziten Konvertierung verwendet werden (beachten Sie, dass dies am Punkt der Definition und des Funktionsaufrufs überprüft wird, da am Punkt der Funktionsdeklaration Parameter- und Rückgabetyp unvollständig sein können).
Zeiger und Referenzen auf eine abstrakte Klasse können deklariert werden.
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) }
Die Definition einer rein virtuellen Funktion kann bereitgestellt werden (und muss bereitgestellt werden, wenn die rein virtuelle Funktion der Destruktor ist): Die Member-Funktionen der abgeleiteten Klasse können die rein virtuelle Funktion der abstrakten Basisklasse frei mit einem qualifizierten Funktionsnamen aufrufen. Diese Definition muss außerhalb des Klassenrumpfes bereitgestellt werden (die Syntax einer Funktionsdeklaration erlaubt weder den rein-spezifizierer = 0 noch einen Funktionsrumpf).
Ein virtueller Aufruf einer rein virtuellen Funktion aus einem Konstruktor oder Destruktor der abstrakten Klasse ist undefiniertes Verhalten (unabhängig davon, ob sie eine Definition hat oder nicht).
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() } };
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 390 | C++98 | ein undefinierter rein virtueller Destruktor könnte aufgerufen werden | in diesem Fall ist eine Definition erforderlich |
| CWG 2153 | C++98 | Rein-Spezifizierer konnte in friend Deklarationen erscheinen | verboten |