Laufzeitpolymorphismus in C++

Laufzeitpolymorphismus in C++

Laufzeitpolymorphismus in C++ mit Beispielen:

In diesem Artikel werde ich Runtime Polymorphism in C++ diskutieren mit Beispielen. Bitte lesen Sie unseren vorherigen Artikel, in dem wir über virtuelle Funktionen in C++ gesprochen haben mit Beispiel.

Laufzeitpolymorphismus in C++:

Dies ist eines der wichtigsten Themen in C++ oder in der Objektorientierung, nämlich Laufzeitpolymorphismus. Laufzeitpolymorphismus wird auch als dynamischer Polymorphismus oder spätes Binden bezeichnet. Beim Laufzeitpolymorphismus wird der Funktionsaufruf zur Laufzeit aufgelöst. Sehen wir uns nun das Beispiel von Runtime Polymorphism in C++ an. Dafür nehmen wir eine Klasse, nämlich Auto, wie im Bild unten gezeigt.

Das ist unsere Autoklasse. Das ist welches Auto? Dies ist ein generisches Auto oder verallgemeinertes Auto. Für jedes 4-Rad, das Passagiere befördert, können wir sagen, dass es ein Auto ist. Das Auto wird also einige Funktionen haben, aber hier haben wir nur Start- und Stoppfunktionen als öffentlich definiert. Die Start-Funktion zeigt Car Started und die Stop-Funktion Car Stopped an. Dann haben wir eine weitere Klasse namens Innova erstellt, wie im folgenden Bild gezeigt.

Die Innova-Klasse erbt öffentlich von der Klasse Car. Das bedeutet, wenn die Innova-Klasse von der Car-Klasse erbt, erhält die Innova-Klasse alles von der Car-Klasse. Aber all diese Dinge, die in der Autoklasse vorhanden sind, sind nur Funktionen, die Start und Stop sind. Haben sie eine Rolle zu spielen? Nein. Sie zeigen nur eine einfache Nachricht an.

Wir haben diese Funktionen in der Innova-Klasse überschrieben. Das bedeutet, dass jetzt beide Klassen dieselbe Funktion haben, aber in der Innova-Klasse sind diese Funktionen überschriebene Funktionen. Jetzt wollen wir eine weitere Klasse schreiben, die Swift-Klasse ist, wie im folgenden Bild gezeigt.

Die Swift-Klasse wird auch von der Car-Klasse geerbt. Dann haben wir innerhalb der Swift-Klasse die Start- und Stop-Funktionen überschrieben. Wir haben dieses Beispiel bereits genommen, als wir von Spezialisierung und Generalisierung gesprochen haben. Dieses Beispiel dient also der Verallgemeinerung. Glaubst du, welche Klasse existierte? Innova existierte und Swift existierte. Dann haben wir gesagt, dass das Autos sind, also haben wir die Klasse Auto definiert.

Jetzt können Sie hier eine Sache beobachten:Die Autoklasse hat zwei Funktionen. Was gibt es dann mit der Autoklasse zu teilen, um sie mit ihren Kindern zu teilen? Wer ist die Kinderklasse? Innova ist eine untergeordnete Klasse und auch Swift ist eine untergeordnete Klasse von Car. Hat die Autoklasse etwas zu teilen? Nein.

Innova und Swift überschreiben beide die Start- und Stoppfunktionen. Also, was ist der Nutzen der Auto-Klasse? Welchen Nutzen haben diese Funktionen, wenn Innova- und Swift-Klassen von dieser erben? Lass uns sehen. Bitte Hauptfunktion beachten. Wir haben Folgendes in die main-Funktion geschrieben.

Hier haben wir einen Zeiger c der Autoklasse erstellt und ihn zuerst dem Innova-Klassenobjekt zugewiesen. Dann haben wir in den nächsten beiden Zeilen mit Hilfe des Zeigers c die Funktionen Start und Stop aufgerufen. Welche Funktion wird nun aufgerufen? Wir haben einen Basisklassenzeiger erstellt und ihn dem abgeleiteten Klassenobjekt zugewiesen, und es gibt Überschreibungsmethoden in der abgeleiteten Klasse. Hier wird die Autoklassenfunktion aufgerufen. Der vollständige Code ist unten angegeben.

Beispiel zum Verstehen der Funktionsüberschreibung in C++
#include <iostream>
using namespace std;

class Car
{
    public:
    void Start()
    {
        cout << "Car Started" << endl;
    }
    void Stop()
    {
        cout << "Car Stopped" << endl;
    }
};

class Innova:public Car
{
    public:
    void Start()
    {
        cout << "Innova Started" << endl;
    }
    void Stop()
    {
        cout << "Innova Stopped" << endl;
    }
};

class Swift:public Car
{
    public:
    void Start()
    {
        cout << "Swift Started" << endl;
    }
    void Stop()
    {
        cout << "Swift Stopped" << endl;
    }
};

int main()
{
    Car *c = new Innova();
    c->Start();
    c->Stop();
    c = new Swift();
    c->Start();
    c->Stop();
    return 0;
}
Ausgabe:

Nehmen wir nun an, wir möchten, dass die Funktion der abgeleiteten Klasse aufgerufen wird, dann müssen wir die Funktionen der Basisklasse als virtuelle Funktionen erstellen. Das heißt, wenn wir wollen, dass die Startfunktion der Innova-Klasse aufgerufen wird, müssen wir die Startfunktion der Autoklasse virtuell machen. Wenn wir möchten, dass die Stop-Funktion der Innova-Klasse aufgerufen werden soll, müssen wir die Stop-Funktion der Car-Klasse virtuell machen. Zum besseren Verständnis sehen Sie sich bitte das folgende Beispiel an.

Beispiel zum Verständnis virtueller Funktionen in C++
#include <iostream>
using namespace std;

class Car
{
    public:
    virtual void Start()
    {
        cout << "Car Started" << endl;
    }
    virtual void Stop()
    {
        cout << "Car Stopped" << endl;
    }
};

class Innova:public Car
{
    public:
    void Start()
    {
        cout << "Innova Started" << endl;
    }
    void Stop()
    {
        cout << "Innova Stopped" << endl;
    }
};

class Swift:public Car
{
    public:
    void Start()
    {
        cout << "Swift Started" << endl;
    }
    void Stop()
    {
        cout << "Swift Stopped" << endl;
    }
};

int main()
{
    Car *c = new Innova();
    c->Start();
    c->Stop();
    c = new Swift();
    c->Start();
    c->Stop();
    return 0;
}
Ausgabe:

Nun rufen wir also c->Start() auf -Funktion, dann wird die Startfunktion der Innova-Klasse aufgerufen. Dies bedeutet, dass die Existenz der Autoklasse virtuell und nicht real ist. Wir verwenden den Begriff Auto als virtuell. Es ist ein allgemeiner Begriff. Es existiert nicht in der realen Welt.

Als Fortsetzung der main-Funktion haben wir in der main-Funktion den gleichen c-Zeiger dem Objekt der Swift-Klasse zugewiesen. Dann haben wir in den nächsten beiden Zeilen c->Start() aufgerufen und c->Stop() Funktionen. Nun, wessen Funktion wird aufgerufen? Jetzt ist das Objekt Swift, also werden die Start- und Stop-Funktionen von Swift aufgerufen. Es ist wie,

Zunächst zeigte c auf Innova, sodass beim Aufrufen der Start- und Stoppfunktion die Meldung als Innova gestartet und Innova gestoppt angezeigt wird.

Wenn wir als Nächstes c dem Swift-Objekt zugewiesen haben, wird nach dem Aufruf der Start- und Stop-Funktion die Nachricht als Swift Started und Swift Stopped angezeigt.

Hier ist der Zeiger derselbe, aber die Objekte sind unterschiedlich. Wenn wir also die Funktion Start aufgerufen haben, wird abhängig vom zugewiesenen Objekt entweder die Startfunktion der Swift-Klasse oder der Innova-Klasse aufgerufen.

Wie Sie sehen können, führen wir dieselben Zeilen aus wie c->Start() und c->Stopp , aber die aufgerufenen Funktionen sind unterschiedlich. Dies ist Runtime Polymorphism in C++.

Wir erreichen Polymorphismus. Dieselbe Anweisung, aber die Funktionsaufrufe sind unterschiedlich, da das erste Objekt Innova und das nächste Objekt Swift war. Das bedeutet, dass Sie jedes Auto haben können, wenn Sie einen Zeiger des Autos einem bestimmten Autoobjekt zugewiesen haben. Wir können jedes Automodell verwenden, das eine eigene Klasse im Programm hat, und diese Klasse sollte von der Autoklasse geerbt werden. Es wird also die Objektfunktion aufgerufen, die dem Car-Zeiger zugewiesen wird. Das ist es. Dies ist ein Beispiel für Laufzeitpolymorphismus in C++.

Lassen Sie uns hier noch ein paar Dinge erweitern. Dies ist ein Beispiel für eine Verallgemeinerung. Welche Klasse gibt es bereits? Die Swift-Klasse und die Innova-Klasse sind bereits vorhanden. Zwei Klassen existieren bereits. Wir haben eine Klasse Car geschrieben, um Polymorphismus zu erreichen. Dann haben wir die gemeinsamen Funktionen in die 3 Klassen geschrieben, die wir in 2 Klassen überschrieben haben. Warum haben wir den Code in der Autoklasse geschrieben? Ist es nützlich? Werden Sie das Objekt der Klasse Auto verwenden? Nein.

Entfernen wir also den Code aus der Car-Klasse und bleibt der Prototyp der Funktionen wie folgt:

Sind das jetzt virtuelle Funktionen? Ja. Haben sie den Körper? Nein. Was ist der Zweck? Das ist nur für das Erreichen von Polymorphismus. Warum schreiben wir Funktionsprototypen? Weil wir wollen, dass diese Funktionen von einer Unterklasse implementiert werden müssen. So wurde diese Autoklasse zu einer Superklasse. Wir möchten, dass die Funktionen von den Unterklassen implementiert werden, z. B. Innova, Swift usw.

Haben wir die abgeleiteten Klassen gezwungen, diese Funktionen zu implementieren? Ja, wir wollen zwingen. Was wollen wir erzwingen? Wir möchten, dass jede Klasse, die von der Autoklasse erbt, diese beiden Funktionen, Start und Stop, überschreiben muss. Sie muss beide Funktionen überschreiben. Wie macht man es obligatorisch? Wir müssen die Funktion in der Autoklasse mit Null gleichsetzen,

Also sind diese Funktionen als reine virtuelle Funktionen bekannt . Wenn Sie einer virtuellen Funktion Null zuweisen, wird sie zu einer rein virtuellen Funktion. Also, was bedeutet es oder was ist der Zweck? Diese Funktionen müssen von den abgeleiteten Klassen überschrieben werden, sonst wird die abgeleitete Klasse zu einer abstrakten Klasse. Und die Klasse Auto ist hier abstrakt.

Und wir können das Objekt einer abstrakten Klasse nicht erstellen, weil es abstrakt ist. Wenn eine Klasse von einer abstrakten Klasse erbt, wird die abgeleitete Klasse ebenfalls abstrakt, wenn diese abgeleitete Klasse die virtuellen Funktionen nicht überschreibt. Wir haben also gesagt, dass diese Funktionen überschrieben werden müssen. Reine virtuelle Funktionen müssen also von den abgeleiteten Klassen überschrieben werden. Und der Zweck einer rein virtuellen Funktion besteht darin, Laufzeitpolymorphismus in C++ zu erreichen.

Beispiel zum Verständnis rein virtueller Funktionen in C++:
#include <iostream>
using namespace std;

class Car
{
    public:
    virtual void Start() = 0;
    virtual void Stop() = 0;
};

class Innova:public Car
{
    public:
    void Start()
    {
        cout << "Innova Started" << endl;
    }
    void Stop()
    {
        cout << "Innova Stopped" << endl;
    }
};

class Swift:public Car
{
    public:
    void Start()
    {
        cout << "Swift Started" << endl;
    }
    void Stop()
    {
        cout << "Swift Stopped" << endl;
    }
};

int main()
{
    Car *c = new Innova();
    c->Start();
    c->Stop();
    c = new Swift();
    c->Start();
    c->Stop();
    return 0;
}
Ausgabe:

Sie können das Objekt der Autoklasse nicht erstellen. Können wir einen Referenzzeiger erstellen? Ja, wir können einen Zeiger auf die Autoklasse haben. Also, welche Autoklasse muss her? Nichts. Nur die Deklaration der Funktion, wo die abgeleiteten Klassen diese Funktionen implementieren müssen. Das ist also ein sehr interessantes und wichtiges Thema in C++.

Schlüsselpunkte des Laufzeitpolymorphismus in C++:
  1. Gleicher Name, unterschiedliche Aktionen
  2. Laufzeit-Polymorphismus wird durch Überschreiben von Funktionen erreicht
  3. Virtuelle Funktionen sind abstrakte Funktionen der Basisklasse
  4. Die abgeleitete Klasse muss die virtuellen Funktionen überschreiben
  5. Ein Basisklassenzeiger, der auf ein abgeleitetes Klassenobjekt zeigt, und eine Überschreibungsfunktion werden aufgerufen

Im nächsten Artikel werde ich auf Abstrakte Klassen in C++ eingehen mit Beispielen. Hier, in diesem Artikel, versuche ich, Runtime Polymorphism in C++ zu erklären mit Beispielen, und ich hoffe, Ihnen gefällt dieser Artikel über Laufzeitpolymorphismus in C++ mit Beispielen. Ich hätte gerne Ihr Feedback. Bitte posten Sie Ihr Feedback, Ihre Fragen oder Kommentare zu diesem Artikel.