Abstrakte Klassen (C++)

Abstrakte Klassen fungieren als Ausdrücke allgemeiner Konzepte, von denen spezifischere Klassen abgeleitet werden können. Sie können kein Objekt eines abstrakten Klassentyps erstellen. Sie können jedoch Zeiger und Verweise auf abstrakte Klassentypen verwenden.

Sie erstellen eine abstrakte Klasse, indem Sie mindestens eine reine virtuelle Memberfunktion deklarieren. Dies ist eine virtuelle Funktion, die mithilfe der reinen Bezeichnersyntax (= 0) deklariert wird. Klassen, die von der abstrakten Klasse abgeleitet sind, müssen die rein virtuelle Funktion implementieren, um nicht selbst als abstrakte Klasse angesehen zu werden.

Betrachten Sie das Beispiel, das in virtuellen Funktionen dargestellt wird. Mit der Account-Klasse soll eine allgemeine Funktionalität gewährleistet werden, aber Objekte vom Typ Account sind zu allgemein, um von Nutzen zu sein. Das bedeutet Account , dass ein guter Kandidat für eine abstrakte Klasse ist:

// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
   Account( double d );   // Constructor.
   virtual double GetBalance();   // Obtain balance.
   virtual void PrintBalance() = 0;   // Pure virtual function.
private:
    double _balance;
};

Diese Deklaration unterscheidet sich von der vorherigen einzig darin, dass PrintBalance mit dem reinen Bezeichner (= 0) deklariert wird.

Einschränkungen für abstrakte Klassen

Abstrakte Klassen können nicht für:

  • Variablen oder Memberdaten

  • Argumenttypen

  • Funktionsrückgabetypen

  • Typen expliziter Konvertierungen

Wenn der Konstruktor für eine abstrakte Klasse eine reine virtuelle Funktion entweder direkt oder indirekt aufruft, ist das Ergebnis nicht definiert. Allerdings können Konstruktoren und Destruktoren für abstrakte Klassen andere Memberfunktionen aufrufen.

Definierte reine virtuelle Funktionen

Reine virtuelle Funktionen in abstrakten Klassen können definiert oder über eine Implementierung verfügen. Sie können solche Funktionen nur mithilfe der vollqualifizierten Syntax aufrufen:

abstract-class-name::function-name()

Definierte reine virtuelle Funktionen sind hilfreich, wenn Sie Klassenhierarchien entwerfen, deren Basisklassen reine virtuelle Destruktoren enthalten. Das liegt daran, dass Basisklassendestruktoren während der Objektvernichtung immer aufgerufen werden. Betrachten Sie das folgende Beispiel:

// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
    base() {}
    // To define the virtual destructor outside the class:
    virtual ~base() = 0;
    // Microsoft-specific extension to define it inline:
//  virtual ~base() = 0 {};
};

base::~base() {} // required if not using Microsoft extension

class derived : public base
{
public:
    derived() {}
    ~derived() {}
};

int main()
{
    derived aDerived; // destructor called when it goes out of scope
}

Das Beispiel zeigt, wie Sie mit einer Microsoft-Compilererweiterung eine Inlinedefinition zu reinem virtuellen ~base()Computer hinzufügen können. Sie können sie auch außerhalb der Klasse definieren, indem Sie die Klasse verwenden base::~base() {}.

Wenn das Objekt aDerived außerhalb des Gültigkeitsbereichs liegt, wird der Destruktor für die Klasse derived aufgerufen. Der Compiler generiert Code, um den Destruktor für die Klasse base nach dem derived Destruktor implizit aufzurufen. Die leere Implementierung für die reine virtuelle Funktion ~base stellt sicher, dass mindestens eine Implementierung für die Funktion vorhanden ist. Ohne diesen Fehler generiert der Linker einen nicht aufgelösten externen Symbolfehler für den impliziten Aufruf.

Hinweis

Im vorherigen Beispiel wird die rein virtuelle Funktion base::~base implizit von derived::~derived aufgerufen. Es ist auch möglich, reine virtuelle Funktionen explizit mithilfe eines vollqualifizierten Memberfunktionsnamens aufzurufen. Solche Funktionen müssen über eine Implementierung verfügen, oder der Aufruf führt zu einem Fehler zur Verknüpfungszeit.

Siehe auch

Vererbung