FSST - Hardwarenahe Programmierung

Vererbung in C++

Inhalt

C++-Seite

Datentypen

GitHub-mbed-os: Drivers

Einleitung und Klassedesign

Aufgabe Klasse Date

Erweitern Sie die Klasse Date, die nur den Tag (day) implementiert hat, ohne Vererbung mit Monat und Jahr.

Lösung?

Klassenableitung

Die Vererbung besagt, dass eine neu zu definierende Klasse die Memerbervariablen und Methoden einer anderen Klasse erben kann. Z.B. besitzt eine Anwendung mehrere Klassen, die eine gemeinsame Struktur aufweisen und nur durch spezielle Methoden und Memerbervariablen auf den jeweiligen Anwendungsfall angepasst sind, können diese Klassen die gemeinsame Funktionalität in einer sogenannten Basisklasse zusammenfassen. Von der Basisklasse können die speziellen Klassen abgeleitet und die speziellen Methoden und Memerbervariablen hinzu gefügt werden, oder es können die Funktionalitäten der geerbten Methoden verändert werden.
Syntax:

class Abgeleitet_Klassenname: public Basis_Klassenname
{ 
	// Deklarationen
};

Bei einer public Ableitung werden die Zugriffsrechte aus der Basisklasse 1:1 in die abgeleitete Klasse übernommen. Damit kann dann auch über ein Objekt der abgeleiteten Klasse auf die public Member der Basisklasse zugegriffen werden.

Konstruktor

Die abgeleitete Klasse erbt im Prinzip alle Member der Basisklasse, außer die Konstruktoren und den Destruktor - auch nicht die privaten Member und friends. Bevor der Konstruktor einer abgeleiteten Klasse ausgeführt wird, wird immer der Konstruktor der Basisklasse gestartet. Umgekehrt ist es beim Destruktor. Hier wird der Destruktor der Basisklasse zuletzt aufgerufen. Dieses Verhalten ist logisch, da abgeleitete Klassen auf den Eigenschaften der Basisklassen aufbauen. Entsprechend muss das Basisobjekt konstruiert sein, bevor der Konstruktor der abgeleiteten Klasse aufgerufen wird. Entsprechendes gilt beim Destruktor. Der Destruktor der Basisklasse muss zuletzt aufgerufen werden, damit das Basisobjekt nicht bereits zerstört ist, wenn die abgeleitete Klasse noch versucht, die Erweiterungen freizugeben.

Parameterunterschiede der Konstruktoren (Initialisierer)
Wenn von einer Basisklasse kein Konstruktor vorhanden ist, der die gleichen Parameter hat wie der Konstruktor der abgeleitet Klasse, dann muss der Konstruktor der Basisklasse explizit aufgerufen werden. Das kann mit einen Initialisierer ähnlich der Initialisierungslisten erfolgen (See how it works: Klasse mit Konstruktor und Initilisierungsliste).
Im folgenden Beispiel hat die Basisklasse lediglich einen Konstruktor, der einen Integer-Wert erwartet. Dadurch gibt es keinen Standardkonstruktor. Die abgeleitete Klasse hat aber einen Standardkonstruktor, was einen Compiler-Fehler zur Folge hätte, weil er kein Gegenstück in der Basisklasse findet. Damit dies nicht geschieht, wird der Konstruktor der Basisklasse explizit als Initialisierer aufgerufen. Bei Aufruf des Standardkonstruktors der abgeleiteten Klasse wird der Basiskonstruktor mit dem Parameter 5 aufgerufen.

class Basis
{
public:
    Basis(int i); // Kein Standardkonstruktor
};

class Abgeleitet : public Basis
{
public:
    Abgeleitet() : Basis(5) // Basiskonstruktor aufrufen
    {
        ...
    }
};

Das Anlegen eines Objekts vom Typ "Abgeleitet" ruft den Standardkonstruktor auf. Ohne den Initialisierer würde der Compiler den Standardkonstruktor von "Basis" aufrufen. Den gibt es allerdings nicht - Compiler-Fehler. Durch den Initialisierer wird der Konstruktor mit dem Integer-Parameter explizit aufgerufen, bevor die Initialisierung von "Abgeleitet" beginnt.

Verwenden von Methoden

Verwenden von Methoden der Basisklasse
Die Vererbung ermöglicht die Wiederverwendung von bereits vorhandenem Programmcode. Es kann durch die Vererbung auf alle Elemente der Basiskiasse, die im public- oder protected-Bereich der Basisklasse stehen, in der abgeleiteten Klasse aufgerufen werden.

Überladen von Methoden bzw. Konstruktoren
Ebenso wie das Überladen der Konstruktoren und Methoden innerhalb einer Klasse funktioniert das Überladen auch bei Vererbung, also das Überladen der Konstruktoren und Methoden in der abgeleiteten Klasse aus der Basisklasse.


Überschreiben von Methoden der Basisklasse
Soll eine Methode der Basisklasse in ihrer Funktionalität vollständig geändert werden, kann man die Methode überschreiben. Dazu wird in der abgeleiteten Klasse eine Methode angelegt, die den gleichen Namen besitzt wie die Methode der Basisklasse, die überschrieben werden soll. Die verdeckte Methode der Basisklasse kann über den Namen der Basisklasse weiterhin aufgerufen werden.


Erweitern von Methoden der Basisklasse
Um die Funktionalität einer geerbten Methode zu erweitern, muss zunächst die Methode der Basisklasse überschreiben werden. In der Methode der abgeleiteten Klasse wird die Methode der Basisklasse aufgerufen. Dazu wird der Klassennamen und den Scope-Operator vor dem Methodennamen angegeben.


Definieren neuer Methoden
Es kann der abgeleiteten Klasse eine Methode im private-, protected- oder public-Bereich der Klassendefinition hinzugefügt werden. Der Namen der Methode, sollte nicht in der Basisklasse vorhanden sein.

Weitere Infos


Virtuelle Methoden

Siehe Verbung und Polymorphie

Statische Elemente - Klassenvariable

Aufgaben Vererbung


All wikipages