Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Diamantvererbung | Überblick Über die Vererbung
C++ OOP
course content

Kursinhalt

C++ OOP

C++ OOP

1. Grundlagen der OOP in C++
2. Konstruktoren und Destruktoren
3. Kapselungsübersicht
4. Überblick Über die Vererbung
5. Überblick Über Polymorphismus

book
Diamantvererbung

Mehrfachvererbung kann zu einer Situation führen, die als Diamantproblem oder Diamantvererbung bekannt ist, was eine bedeutende Herausforderung in objektorientierten Programmiersprachen darstellt, die Mehrfachvererbung unterstützen.

Dies tritt auf, wenn eine Unterklasse von zwei oder mehr Klassen erbt, die selbst von einer gemeinsamen Oberklasse erben. Der Begriff Diamant wird verwendet, weil das Vererbungsschema die Form eines Diamanten hat.

cpp

main

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

Das Hauptproblem bei der Diamantvererbung ist die Mehrdeutigkeit, die sie erzeugt. Da Diamond sowohl von Derived1 als auch von Derived2 erbt, die wiederum von Base erben, gibt es zwei Kopien von Base innerhalb eines Objekts von Diamond. Dies kann zu Mehrdeutigkeit führen. Zum Beispiel:

cpp

main

copy
123456789101112131415
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Lösung des Problems

Das Schlüsselwort virtual hilft, dieses Problem zu vermeiden. Sie können diese Mehrdeutigkeit durch virtuelle Vererbung ansprechen, indem Sie das Schlüsselwort virtual verwenden. Wenn ein Diamant virtuell geerbt wird, stellt C++ sicher, dass nur eine Kopie der Oberklasse vorhanden ist, selbst wenn sie mehrfach über verschiedene Pfade geerbt wird.

cpp

main

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};

Hinweis

Versuchen Sie, das Mehrdeutigkeitsproblem im vorherigen Beispiel durch die Nutzung der virtuellen Vererbung zu lösen.

Implementierung der Diamantvererbung

Um die Diamantvererbung effektiv zu implementieren:

  1. Verwenden Sie das Schlüsselwort virtual in der Oberklasse-Deklaration in den Zwischenklassen;
  2. Stellen Sie sicher, dass virtuelle Vererbung in allen Pfaden der Vererbungshierarchie konsistent verwendet wird;
  3. Achten Sie auf die Reihenfolge der Aufrufe von Konstruktoren und Destruktoren.

Auflösung von Mehrdeutigkeiten

Eine der Herausforderungen der Mehrfachvererbung besteht auch darin, mit potenziellen Mehrdeutigkeiten umzugehen, wenn es um Mitglieder mit denselben Namen geht.

cpp

main

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Wenn beide Superklassen Mitglieder mit demselben Namen haben, weiß die Unterklasse möglicherweise nicht, welches sie verwenden soll. Um solche Mehrdeutigkeiten zu lösen, können Sie den Bereichsauflösungsoperator (::) verwenden, um anzugeben, auf welches Mitglied der Basisklasse Sie zugreifen möchten. Zum Beispiel:

cpp

main

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 4. Kapitel 5
We're sorry to hear that something went wrong. What happened?
some-alt