© FOTOGRIN/Shutterstock.com
Als objektorientierte Programmiersprache verlässt sich C++ häufig auf die Implementierung von Vererbung. Mit dieser Funktion können Sie Attribute und andere Merkmale einer Klasse ändern und wiederverwenden sowie die Menge an benötigtem Code reduzieren. Lesen Sie weiter, um genau zu erfahren, was Vererbung ist und welche Arten von Vererbung Sie in C++ verwenden können.
Was ist Vererbung?
Ähnlich wie wir bestimmte Eigenschaften „erben“ können von unseren Eltern können Klassen in C++ Mitglieder von einer anderen Klasse erben. Auf diese Weise wird die Klasse, deren Mitglieder geerbt werden, als Basis-oder Elternklasse definiert, und die Klasse, die diese Merkmale erbt, wird als abgeleitete Klasse, Unterklasse oder Kindklasse bezeichnet. Da dies die Wiederverwendung von Mitgliedern der übergeordneten Klasse ermöglicht, müssen diese Mitglieder nicht neu definiert werden. Daher können Sie Zeit sparen, unnötigen Code zu implementieren.
Es gibt Ähnlichkeiten mit der Friend-Funktion und der Friend-Klasse, da diese Funktionen und Klassen den Zugriff auf Mitglieder anderer Klassen ermöglichen. Allerdings erlaubt friend den Zugriff auf private Mitglieder, während die Vererbung dies nicht tut.
Welche Arten der Vererbung gibt es in C++?
Es gibt 5 Arten der Vererbung in C++. Diese sind:
Einfache VererbungMehrstufige VererbungMehrfache VererbungHybride VererbungHierarchische Vererbung
Schauen wir uns diese an.
Einfache Vererbung
Die einfachste Vererbungsmethode ist die einer Klasse erbt die Mitglieder einer anderen Klasse. Dies kann mit folgendem Code gezeigt werden:
#include class BaseClass { public: int x; }; Klasse DerivedClass: public BaseClass{ public: int y; }; int main() { DerivedClass obj; obj.x=10 obj.y=20 std::cout”Elementvariable der Basisklasse x=”std::endl; std::cout”Abgeleitete Klassenmitgliedsvariable y=”obk.y std::endl; 0 zurückgeben; }
Hier haben wir die Basisklasse als „BaseClass“ definiert, mit Member „x“, das öffentlichen Zugriff hat. Die abgeleitete Klasse ist als „DerivedClass“ definiert, die öffentlich von „BaseClass“ erbt. Die abgeleitete Klasse selbst hat ein öffentliches Element namens „y“. Wir erstellen eine Instanz der abgeleiteten Klasse namens „DerivedClass obj“ und legen die x-und y-Werte fest. Mit diesem Objekt greifen wir auf das Mitglied „x“ der übergeordneten Klasse zu, und die x-und y-Werte werden wie im Screenshot gezeigt an die Konsole ausgegeben.
Einzelvererbung am Beispiel gezeigt.
©”TNGD”.com
Private Mitglieder erben
Es ist erwähnenswert, dass die abgeleitete Klasse alle Mitglieder der Elternklasse erben könnte, weil sie öffentlichen Zugriff haben. Wenn Mitglieder jedoch als privat deklariert werden, können diese nicht direkt vererbt werden. Eine Möglichkeit, dies zu umgehen, besteht darin, bestimmte Funktionen, die auf diese Mitglieder wirken, zu vererben. Auf diese Weise können Sie indirekt auf diese Mitglieder zugreifen. Nehmen Sie das folgende Beispiel:
class Base{ private: int a; public: Base(int a) a(a) {} int getA() const { return a; } }; Klasse Abgeleitet: öffentliche Basis { Öffentlichkeit: Abgeleitet (int a): Basis (A) {} }; int main () { Abgeleitet d (5); std::cout”Wert des abgeleiteten Objekts:”d.getA() std::endl; 0 zurückgeben; }
Hier haben wir eine übergeordnete Klasse als „Basis“ und eine abgeleitete Klasse als „Derived“ definiert. Das Element „a“ der Elternklasse ist privat, also nicht direkt für die abgeleitete Klasse zugänglich. Aber wir haben einen Konstruktor in der Basisklasse, der das Integer-Argument von „a“ nimmt und das private Mitglied „a“ setzt. Die abgeleitete Klasse hat selbst einen Konstruktor, „Derived(int a): Base (a) {}“, der das Integer-Argument „a“ nimmt und es an den Konstruktor der Basisklasse übergibt. Da die Funktion „getA()“ geerbt wurde, wird indirekter Zugriff auf das Element „a“ der übergeordneten Klasse erreicht.
Mit der Funktion „main“ nehmen wir eine Instanz „d“ von die abgeleitete Klasse und definieren Sie sie mit einem Argument von 5. Die Funktion „getA()“ wird auf dieser Instanz aufgerufen und die Ausgabe wird gedruckt. Dies wird im Screenshot gezeigt.
Wie man private Mitglieder vererbt, gezeigt in einem Beispiel.
©”TNGD”.com
Private vs. geschützte Klassen
Es würde sich an dieser Stelle lohnen unterscheiden zwischen privaten und geschützten Klassen. Während auf private Klassenmitglieder nur indirekt durch abgeleitete Klassen zugegriffen werden kann, kann auf geschützte Klassenmitglieder vollständig durch eine abgeleitete Klasse zugegriffen werden. Aber auf sie kann nur innerhalb dieser Klassenhierarchie zugegriffen werden und nicht außerhalb (dies wäre öffentlicher Zugriff).
Nur-Methoden-Vererbung
Diese Beispiele haben auch Feldvererbung gezeigt, wobei das Feld „a“ geerbt wurde. Sie können aber auch eine reine Methodenvererbung haben, bei der eine Methode verwendet wird, um das Verhalten der Klasse zu definieren. Ein Beispiel dafür ist unten gezeigt:
#inlude class Base { public: virtual void bar() { std::cout”Base::bar()”std::endl; } }; Klasse Abgeleitet: public Base { public: virtual vaide bar() { std::cout”Derived::bar()”std::endl; } }; int main() {Basis* b=neu Derived(); b->bar();//gibt”Derived::bar()”aus delete b; 0 zurückgeben; }
Wie zuvor haben wir eine Elternklasse „Base“ und eine abgeleitete Klasse „Derived“. „Base“ hat eine virtuelle Methode „bar()“. Dies wird als virtuell bezeichnet, da es keine Implementierung in der übergeordneten Klasse hat und von der abgeleiteten Klasse überschrieben werden kann. Die Implementierung von „bar()“ wird in der abgeleiteten Klassendefinition bereitgestellt. Wir können sehen, dass ein Zeiger „b“ innerhalb der Funktion „main()“ erstellt und mit dem Objekt „Derived“ initialisiert wird. „Derived::bar()“ überschreibt „Base::bar()“, da es sich um eine virtuelle Funktion handelt. Die Implementierung innerhalb der abgeleiteten Klasse wird aufgerufen, die die Ausgabe „Derived::bar()“ ausgibt, wie im Screenshot zu sehen.
Ein Beispiel für reine Methodenvererbung.
©”TNGD”.com
Mehrstufige Vererbung
Es gibt viele Fälle, in denen Sie eine abgeleitete Klasse aus einer Klasse erstellen möchten, die bereits von einer übergeordneten Klasse abgeleitet wurde. Dies wird als mehrstufige Vererbung bezeichnet. Was die Vererbungsarten in C++ betrifft, so ist diese ziemlich intuitiv. Ein solches Beispiel ist die Arbeit mit Fahrzeugtypen. In dieser Situation haben Sie möglicherweise eine übergeordnete Klasse von „Fahrzeugen“, die bestimmte Methoden und Parameter definiert, die für die Fahrzeuge gelten, mit denen Sie arbeiten, z. B. Autos und Motorräder. Dies könnten beide von dieser übergeordneten Klasse abgeleitete Klassen mit ihren eigenen spezifischen Eigenschaften sein. Aber da Sie möglicherweise bestimmte Arten davon haben, könnten Sie dann abgeleitete Klassen wie „PerformanceCar“ erstellen, die dann ihre eigenen anwendbaren Eigenschaften haben würden.
Wir können mit dem folgenden Code veranschaulichen, wie dies funktioniert:
#include #include class Vehicle { public: std::string type; std::stringfarbe; }; Klasse Auto: öffentlich Fahrzeug { öffentlich: std::string model; int Jahr; }; Klasse ElectricCar: public Car { public: int batteryCapacity; }; int main() { ElectricCar Tesla; tesla.type=”Elektroauto”; tesla.color=”Rot”; tesla.model=”Modell S”; Tesla.Jahr=2021; tesla.batteryCapacity=100; std::cout”Typ:”tesla.type std::endl; std::cout”Farbe:”tesla.color std::endl; std::cout”Modell:”tesla.model std::endl; std::cout”Jahr:”tesla.year std::endl; std::cout”Batteriekapazität:”tesla.batteryCapacity std::endl; 0 zurückgeben; }
In diesem Beispiel haben wir die Basisklasse „Vehicle“, die abgeleitete Klasse „Car“ und eine weitere abgeleitete Klasse namens „ElectricCar“. Die Klasse „Vehicle“ hat die Member „type“ und „color“, die Klasse „Car“ hat die Member „model“ und die Integer-Variable „year“ und die Klasse „ElectricCar“ hat die Integer-Member-Variable „batteryCapacity“. Die main-Funktion erstellt eine Instanz der „ElectricCar“-Klasse und setzt alle ihre geerbten Member-Variablen mit bestimmten Werten. Diese Variablen werden dann an die Konsole ausgegeben.
Mehrstufige Vererbung in einem Beispiel implementiert, zusammen mit seiner Ausgabe.
©”TNGD”.com
Mehrfachvererbung
Genauso wie wir eine Klasse ableiten lassen können von einer bereits abgeleiteten Klasse können wir eine Klasse haben, die von mehr als einer Basisklasse abgeleitet ist. Wir können dies demonstrieren, indem wir mit unserer Auto-Analogie fortfahren:
#include #include class Vehicle { public: std::string type; std::stringfarbe; }; class ElectricEngine { public: int batteryCapacity; }; Klasse SportsCar { public: int topSpeed; }; class ElectricSportsCar: public Vehicle, public ElectricEngine, public SportsCar { öffentlich: std::string model; int Jahr; }; int main() { ElectricSportsCar Tesla; tesla.type=”Elektroauto”; tesla.color=”Rot”; tesla.model=”Roadster”; Tesla.Jahr=2022; tesla.batteryCapacity=200; tesla.topSpeed =250; std::cout”Typ:”tesla.type std::endl; std::cout”Farbe:”tesla.color std::endl; std::cout”Modell:”tesla.model std::endl; std::cout”Jahr:”tesla.year std::endl; std::cout”Batteriekapazität:”tesla.batteryCapacity”kWh”std::endl; std::cout”Höchstgeschwindigkeit:”tesla.topSpeed ”mph”std::endl; 0 zurückgeben; }
Wir haben hier drei Klassen, „Vehicle“, „ElectricEngine“ und „SportsCar“. Dies sind alles Basisklassen, deren Eigenschaften von der abgeleiteten Klasse „ElectricSportsCar“ geerbt werden. Wie zuvor hat jede der übergeordneten Klassen ihre eigenen Variablen. Eine Instanz von „ElectricSportsCar“ wird erstellt, ihren Eigenschaften werden Werte zugewiesen und diese werden dann auf der Konsole ausgegeben.
Ein Beispiel für Mehrfachvererbung.
©”TNGD”.com
Hierarchische Vererbung
Wir kommen zum Ende der verschiedenen Arten der Vererbung in C++. Hier ist die Situation etwas differenzierter. Obwohl die mehrstufige Vererbung technisch gesehen eine Hierarchie erzeugt, unterscheidet sich dies von der sogenannten hierarchischen Vererbung. Wenn Sie mehrere abgeleitete Klassen aus einer übergeordneten Klasse erstellen, wird dies als hierarchische Vererbung bezeichnet. Dies ist nützlich, wenn Sie verwandte Klassen aus einer übergeordneten Klasse erstellen müssen, aber jede mit ihren eigenen Eigenschaften. Der folgende Code zeigt dieses Beispiel.
class Vehicle { public: std::string type; std::stringfarbe; }; Klasse Auto: öffentlich Fahrzeug { öffentlich: std:: string model; int Jahr; }; Klasse LKW: öffentliches Fahrzeug {öffentlich: int Kapazität; };
Auch hier haben wir die Elternklasse „Vehicle“, und sowohl die Klassen „Car“ als auch „Truck“ sind davon abgeleitet. Beide Klassen erben die Variablen „Typ“ und „Farbe“, fügen aber auch ihre eigenen Eigenschaften hinzu. Nämlich „Modell“ und „Baujahr“ für die Klasse „Auto“ und „Kapazität“ für die Klasse „Lkw“. Im ersten Screenshot sehen wir den Code, der mit der Funktion „main()“ implementiert wurde, mit einer Instanz jeder erstellten Klasse und ihren gesetzten Attributen. Der zweite Screenshot zeigt die Ausgabe in der Konsole.
Hierarchische Vererbung in einer Klasse implementiert.
©”TNGD”.com
Die Ausgabe des obigen Beispiels.
©”TNGD”.com
Hybrid-Vererbung
Etwas komplexer wird die Situation bei der hybriden Vererbung. Hier werden verschiedene Arten der Vererbung in C++ in einer Klassenhierarchie zusammengefasst. Obwohl dies komplex werden kann, ist es manchmal für die Vorgänge erforderlich, die Sie ausführen müssen. Betrachten Sie die folgende Situation:
#include #include class Vehicle { public: std::string type; std:: Zeichenfolgenfarbe; }; Klasse Motor {öffentlich: int PS; }; Klasse Auto: öffentlich Fahrzeug, öffentlich Motor { öffentlich: std::string model; int Jahr; }; Klasse ElectricCar: public Car { public: int batteryCapacity; }; in main() { ElectricCar Tesla; tesla.type=”Elektroauto”; tesla.color=”Rot”; tesla.model=”Modell S”; tesla.Pferdestärke=300; Tesla.Jahr=2021; tesla.batteryCapacity=100; tesla.type=”Elektroauto”; std::cout”Typ:”tesla.type std::endl; std::cout”Farbe:”tesla.color std::endl; std::cout”Pferdestärke:”tesla.Pferdestärke std::endl; std::cout”Modell:”tesla.model std::endl; std::cout”Jahr:”tesla.year std::endl; std::cout”Batteriekapazität:”tesla.batteryCapacity std::endl; 0 zurückgeben; }
Wie zuvor haben wir die übergeordnete Klasse „Vehicle“, aber auch die übergeordnete Klasse „Engine“. Wir haben ein Beispiel für Mehrfachvererbung, bei dem die Klasse „Auto“ sowohl von den Klassen „Fahrzeug“ als auch „Motor“ abgeleitet wird. Die Klasse „ElectricCar“ wird dann von der Klasse „Car“ abgeleitet, die ein Beispiel für mehrstufige Vererbung ist, da es sich um einen spezialisierteren Autotyp handelt. Daher haben wir ein Szenario, in dem eine hybride Vererbung stattfindet. Daher kann die hybride Vererbung nützlich sein, um komplexe Beziehungen zu vereinfachen und zu verstehen und den Code leichter zu warten.
Das erste Bild veranschaulicht die Codeimplementierung, in der wir eine Instanz von erstellt haben Klasse „ElectricCar“ mit ihrem Attributsatz aus allen übergeordneten Klassen. Die gedruckte Ausgabe ist im zweiten Bild zu sehen.
Hybridvererbung in einer Klasse implementiert.
©”TNGD”.com
Die Ausgabe des obigen Beispiels.
©”TNGD”.com
Ein Hinweis zur Mehrdeutigkeit
Ein sehr häufiges Problem, das beim Umgang mit mehreren Klassen auftreten kann, ist das Problem der Mehrdeutigkeit. Hier haben Sie identische Mitgliedsvariablen oder Funktionen in zwei oder mehr Klassen. Der Compiler kann dann auf Fehler stoßen, da er nicht entscheiden kann, welches Member für die Operation verwendet werden soll, die Sie auszuführen versuchen. Betrachten Sie den folgenden Code:
#include class A { public: void foo() {std::cout”A:foo()”std::endl;} }; Klasse B { public: void foo() {std::cout”B::foo()”std::endl;} }; Klasse C: öffentlich A, öffentlich B { öffentlich: }; int main () { C c; c.foo();//Compilerfehler: Mehrdeutiger Aufruf von foo() von A und B return 0; }
Hier haben wir eine Funktion namens „foo()“ sowohl in der Klasse „A“ als auch in der Klasse „B“. Da die Klasse „C“ von diesen beiden Klassen geerbt hat, tritt beim Kompilieren ein Fehler auf. Dies kann auf verschiedene Arten gelöst werden:
Umbenennen der widersprüchlichen Funktion oder Variablen in der übergeordneten oder abgeleiteten Klasse, um Verwirrung zu vermeiden. Verwenden des Bereichsauflösungsoperators (::), um die Klasse anzugeben, die die gewünschte Mitgliedsfunktion enthält. Virtuelle Vererbung arbeitet nach einem ähnlichen Konzept wie die zuvor erwähnte virtuelle Funktion. Dies kann es einer abgeleiteten Klasse ermöglichen, von übergeordneten Klassen zu erben, ohne die Basisklasse zu duplizieren, die diese übergeordneten Klassen gemeinsam nutzen. Überschreiben der widersprüchlichen Funktion durch Neudefinition der Funktion in der abgeleiteten Klasse mit einer spezialisierten Implementierung. Ein Mehrdeutigkeitsfehler illustriert.
©”TNGD”.com
Zusammenfassung
Es gibt 5 Hauptarten der Vererbung in C++, die Sie verwenden können, jede mit ihren eigenen spezifischen Anwendungsfällen. Während die Einzelvererbung für relativ einfache Vorgänge geeignet sein kann, sind bei der Arbeit mit komplexen Objekten und Beziehungen möglicherweise andere Arten wie Mehrfachvererbung, mehrstufige, hierarchische und hybride Vererbung geeigneter. Diese können nützlich sein, um den Code intuitiver und pflegeleichter zu machen und die Beziehung zwischen Klassen besser darzustellen.
Vererbung in C++ erklärt, mit Beispielen FAQs (häufig gestellte Fragen)
Was sind Elternklassen und abgeleitete Klassen?
Eine Elternklasse, auch Basisklasse genannt, ist die Klasse, von der geerbt wird. Andererseits erbt eine abgeleitete Klasse, Unterklasse oder Kindklasse Eigenschaften und Attribute von der Elternklasse.
Was ist Vererbung in C++?
Vererbung ist ein Prozess, mit dem Sie eine abgeleitete Klasse aus einer übergeordneten oder Basisklasse erstellen können, die Eigenschaften und Elementfunktionen von der übergeordneten Klasse erbt. Dies kann nützlich sein, um komplizierte Beziehungen darzustellen und die Notwendigkeit einer wiederholten Codeimplementierung zu reduzieren.
Welche verschiedenen Arten der Vererbung gibt es in C++?
Es gibt sie 5 Hauptarten der Vererbung in C++ – einfach, mehrfach, mehrstufig, hierarchisch und hybrid. Single und Multiple beziehen sich auf eine einzelne Klasse, die jeweils von einer oder mehr als einer Basisklasse abgeleitet ist. Vererbung auf mehreren Ebenen bedeutet, dass eine Klasse von einer abgeleiteten Klasse abgeleitet wird. Hierarchische Vererbung bezieht sich darauf, wenn mehrere Klassen von einer Basisklasse abgeleitet werden, und hybride Vererbung bedeutet, dass eine Mischung aus diesen anderen Typen verwendet wird.
Wie implementieren Sie Vererbung in C++?
Um eine Klasse von einer übergeordneten Klasse erben zu lassen, verwenden Sie einen Doppelpunkt (:), gefolgt von der Zugriffskennung (in diesem Fall entweder öffentlich oder geschützt) und dem Namen der Basisklasse.
Was sind öffentliche, geschützte und private Mitglieder?
Öffentliche Mitglieder sind von überall innerhalb eines Programms vollständig sichtbar und zugänglich und können von jeder Funktion innerhalb oder außerhalb der Klasse aufgerufen werden. Auf geschützte Member kann von abgeleiteten Klassen zugegriffen werden, sie können also vererbt werden. Auf private Elemente kann von keiner Funktion außerhalb der Klasse zugegriffen werden, und sie sind für abgeleitete Klassen unsichtbar. Private Mitglieder können jedoch indirekt sein, wenn eine öffentliche Funktion vererbt wird, die auf sie wirkt.
Was ist der Unterschied zwischen öffentlicher, privater und geschützter Vererbung?
Bei der öffentlichen Vererbung werden alle öffentlichen Mitglieder der Basisklasse öffentliche Mitglieder der abgeleiteten Klasse, und ähnlich werden geschützte und private Mitglieder. Bei geschützter Vererbung werden sowohl öffentliche als auch geschützte Member vererbt, auf private Member kann jedoch nicht zugegriffen werden. Private Vererbung bedeutet, dass öffentliche und geschützte Mitglieder private Mitglieder der abgeleiteten Klasse werden und wie immer private Mitglieder unsichtbar bleiben.
Wie lösen Sie Mehrdeutigkeiten bei der Vererbung auf?
Sie können Mehrdeutigkeiten auflösen, indem Sie den Bereichsauflösungsgenerator verwenden, virtuelle Vererbung verwenden oder die widersprüchlichen Funktionen umbenennen oder neu definieren.