Abstrakte Klassen und C ++

C ++ unterstützt späte Bindung, das ist, wenn es einen Methodenaufruf auf dem Laufzeittyp (oder dynamischen Typ) des Zielobjekts basierend löst, anstatt seine deklarierten Typ (oder statische Typ). Dies wird in der folgenden C ++ Code-Schnipsel demonstriert:

#einschließen using namespace std-Klasse Ofen {public: virtual void Koch () {cout lt; lt; "Kochen mit einem Ofen" lt; lt; Endl -}} - Klasse Mikrowellen: public Ofen {public: virtual void Koch () {cout lt; lt; "Kochen mit der Mikrowelle" lt; lt; Endl -}} - Leere prepareMeal (Ofen Backofen) {oven.cook () -}

In der Funktion prepareMeal (), der Anruf an oven.cook () kann passieren zu Backofen :: kochen () oder Mikrowellen :: kochen () von der Laufzeit abhängig (die "eigentliche") Art des Ofen Objekt übergeben.

Das virtuell Stichwort ist hier von entscheidender Bedeutung. Ohne sie die Koch() Verfahren würde früh, auf der Grundlage der Kompilierung-Typ gebunden werden, und rufen Sie Backofen :: kochen () jedes Mal. Einmal erklärte virtuellen in die Ofen Klasse ist das Verfahren davon ausgegangen, in jeder Unterklasse virtuell sein, aber es tut nicht weh, die Erklärung zu wiederholen, so dass die Leser verstehen.

Das folgende einfache Programm demonstriert dieses Prinzip in der Praxis:

int main () {Ofen Ofen-prepareMeal (Backofen) -MicrowaveOven mo-prepareMeal (mo) -return 0-}

In diesem Programm wird der Anruf an Koch() erzeugt zwei verschiedene Ausgaben von der Art des Ofens in Abhängigkeit:

Kochen mit einem ovenCooking mit Mikrowelle

Es ist nicht immer der Fall, dass ein Verfahren in der Basisklasse definiert werden können. Bedenke die Ofen Wenn mehr sorgfältig. Es gibt eine Reihe von verschiedenen Arten von Öfen - herkömmliche Öfen, Backöfen und Mikrowellenherde - aber man könnte argumentieren, dass es keine tatsächliche Ofen ist, die nicht einer dieser Unterklassen gehört. Sie kann in der Lage sein, zu sagen, wie die verschiedenen Arten von Öfen der führen Koch Betrieb - das ist, was für ein ConventionalOven :: kochen () und Mikrowellen :: kochen () tun können definiert werden sollte. Es ist wahrscheinlich nicht möglich, welche Maßnahmen zu definieren, Backofen :: kochen () durchführen sollten.

Man kann nicht einfach verlassen Backofen :: kochen () nicht angemeldete in einer stark typisierten Sprache wie C ++. Sie können jedoch erklären ein Verfahren, aber lassen Sie es unimplemented wenn keine Implementierung vorhanden ist. Man verwendet die folgende merkwürdige Syntax, dies zu tun:

Klasse Ofen {public: virtual void Koch () = 0 -} -

Dieser Code deklariert eine Methode Ofen::Koch() das heißt Ende gebunden, jedoch nicht die Methode implementieren. In der Tat geht es weiter, indem er sagte, dass das Verfahren nicht durchgeführt werden. In C ++ ist ein solches Verfahren wird gesagt, dass rein virtuelle. C ++ Programmierer verwenden auch den Begriff bevorzugt in vielen anderen stark typisierte Computersprachen: abstrakt. Das Ofen Klasse wird gesagt, abstrakt zu sein.

Eine abstrakte stellt eine Eigenschaft, die Sie die Klasse wissen, besitzt aber nicht wissen, wie eindeutig in der aktuellen Klasse zu implementieren.

Eine Klasse ist abstrakt, wenn sie eine oder mehrere rein virtuelle Methoden. Die Bedeutung dieser Erkenntnis ist, dass Sie nicht eine abstrakte Klasse instanziiert kann. So ist die folgende nicht mehr zulässig:

int main () {Ofen Ofen-prepareMeal (Backofen) -return 0-}

Der Grund dafür ist ganz einfach: Wenn Sie ein Objekt der Klasse erstellt Ofen und dann versucht, aufzurufen oven.cook (), was tun sollte der Compiler?

Auf einer philosophischen Ebene, ist es in Ordnung zu sagen, dass es einige gemeinsame Begriff genannt Ofen dass beschreibt herkömmliche Öfen und Mikrowellenherde und Backöfen. Diese Bezeichnung Ofen Konzept ist üblich, weil es die Ähnlichkeiten in allen diesen Subklassen bindet up. Aber es gibt kein Beispiel eines Ofens, der nicht einer der Unterklassen ist von Ofen.

Eine Unterklasse einer abstrakten Klasse ist selbst abstrakt, bis alle rein virtuelle Methoden wurden von nicht-abstrakte außer Kraft gesetzt wurde (das heißt, Beton) Versionen. So ist die Klasse Mikrowelle im vorherigen Codeausschnitt ist nicht abstrakt - auch wenn Ofen abstrakt waren - weil sie überschreibt Koch() mit seiner eigenen konkreten Version.

Beachten Sie, dass es nichts falsch mit der Funktion ist prepareMeal () wie folgt definiert:

nichtig prepareMeal (Ofen Backofen) {oven.cook () -}

Auch wenn das Argument wird erklärt eine sein Ofen, sie kann nur mit einer gewissen Unterklasse aufgerufen werden, Ofen, sowie Mikrowelle oder ConventionalOven, wofür Koch() ist definiert.

Menü