Mehrfachvererbung in C ++
Wenn ein C ++ Klasse von einer anderen erben kann, dann sofort stellt sich die Frage: "Kann eine Klasse erben von zwei (oder mehr) Klassen?" Die Antwort in eine unqualifizierte "Ja."
Menu
Es kann wertvoll sein, ein reales Beispiel der Mehrfachvererbung zu sehen, zu verstehen, warum dies eine Fähigkeit wert ist. Die meisten Universitäten bieten Arbeitsplätze Studenten als Tutoren zu absolvieren. Diese Personen sind noch Studenten und verfügen über alle Eigenschaften eines Studenten -, sondern darüber hinaus, sie sind auch die Eigenschaften eines Instruktors gewährt. So logisch, sieht ihre Vererbungsbaum wie folgt aus:
Ausgedrückt in C ++, dies würde wie folgt aussehen:
Klasse Schüler {public: double gpa () - bool einschreiben (Kurs) -bool Pay (Doppel-Dollar) -} - Klasse Instructor {public: Doppel Grad (Artifact) -bool (Kurs) lehren -bool GetPaid (Doppel-Dollar) -} -Klasse TeachingAssistant: public Student, öffentliche Instructor {public: Instructor Berater (Ausbilder) -Instructor Berater () -} -
Der einzige Unterschied zwischen diesem Beispiel und Beispiele für einfache Vererbung ist das Auftreten von zwei Klassennamen nach der Erklärung der Lehrassistent.
In Anbetracht der Klassendefinitionen nur gezeigt, die alle der folgenden kann gesagt werden:
TeachingAssistant ta - // erhalten eine Note wie ein studentdouble d = ta.gpa () - // Klasse ein Papier wie ein instructorta.grade (document) - // Ich kann eine ta an eine Funktion, die eine Studentvoid Partei erwartet (Student ) -Partei (ta) - // oder eine Funktion, die ein Instructorvoid Soiree (Ausbilder) -soiree (ta) erwartet -
So weit, ist es gut. Was ist, nicht über die Mehrfachvererbung zu mögen?
Mehrere Zweideutigkeiten
Überprüfen Schüler und Lehrer Klassen teilen sich diese beiden Klassen eine Eigenschaft: eine Universität zugewiesenen Identifikationsnummer. Aber wenn Sie versuchen, diese Eigenschaft wie folgt hinzufügen, erhalten Sie nichts anderes als Beschwerden von C ++:
Klasse Schüler {public: IntID () - Doppel gpa () - bool (Kurs) -bool Pay (Doppel Dollar) einschreiben -} - Klasse Instructor {public: int id () - Doppel-Grad (Artifact) lehren -bool (Kurs) -bool GetPaid (Doppel-Dollar) -} - Klasse TeachingAssistant: public Student, öffentliche Instructor {public: Instructor Berater (Ausbilder) -Instructor Berater () -
};
Dieses Problem wird grafisch dargestellt, hier:
Das Problem ist, dass jetzt, wenn Sie etwas sagen wie:
TeachingAssistant ta-cout lt; lt; "TA-ID ist" lt; lt; ta.id () - // denen id?
welche Ich würde() vorgesehen ist - derjenige, der Lehrassistent Abgeleitet von Schüler oder derjenige, der es erbt von Lehrer? Die Zweideutigkeit kann durch Angabe der Pfad zu lösen Ich würde (bekannt als qualifizierten Namen) so was:
cout lt; lt; "TA Schüler-ID ist" lt; lt; ta.Student :: id () -
Jetzt gibt es keine Zweideutigkeit. Durch die Basisklasse angibt, ist C ++, sagte die Ich würde() nehmen.
Die Lösung der Mehrdeutigkeit: Erster Versuch
Aber was, wenn die beiden Instanzen von Ich würde() sind nicht anders? Nehmen wir an, wie viele Universitäten, eine bestimmte Hochschule sowohl Studenten und Dozenten eine eindeutige Identifikationsnummer zuweist. In diesem Fall ist wollte, was wirklich ist die Situation in der folgenden Abbildung dargestellt: Jetzt ein Lehrassistent hat nur eine einzige Ich würde() Eigentum.
Um zu versuchen, diesen Zustand in C ++ zum Ausdruck bringen, dass das folgende geschrieben:
Klasse Academic {public: int id () -} - Klasse Student: public Academic {public: double gpa () - bool einschreiben (Kurs) -bool Pay (Doppel-Dollar) -} - Klasse Ausbilder: public Academic {public: Doppel Grad (Artefakt) -bool lehren (Kurs) -bool GetPaid (Doppel-Dollar) -} - Klasse TeachingAssistant: public Student, öffentliche Instructor {public: Instructor Berater (Ausbilder) -Instructor Berater () -} -
Leider (und recht überraschend), ist dieser Ansatz nicht das Problem überhaupt lösen. Ein Verweis auf ta.id () ist nach wie vor unklar. Es stellt sich heraus, dass dieser Code nicht mit dem vorhergehenden image- statt schafft, ist es, die Situation hier gezeigt erstellt:
Es scheint, dass Lehrassistent jetzt erbt akademisch zweimal - einmal durch seine Schüler-ness, und wieder durch seine Lehrer-ness. Es hat jetzt ein Student :: Academic :: id () und ein Ausbilder :: Academic :: id ().
Die Lösung der Mehrdeutigkeit
Um zu erreichen, was in C ++ in der dritten Figur dieses Artikels angezeigt wird, müssen Sie wieder auf etwas C ++ Anrufe fallen virtuelle Vererbung. Diese Funktion erscheint in Aktion wie folgt:
Klasse TeachingAssistant: virtuelle öffentliche Student, virtuellen öffentlichen Instructor {public: Instructor Berater (Ausbilder) -Instructor Berater () -} -
Die Verwendung des virtuell Stichwort sagt C ++ alle gängigen Basisklassen zu kombinieren, Schüler und Lehrer könnte teilen. Die folgenden nicht mehr generiert einen Compiler-Fehler:
cout lt; lt; "TA Schüler-ID ist" lt; lt; ta.id () - // kein Fehler jetzt
Mit virtuellen Vererbung, Lehrassistent erbt eine und nur eine Kopie akademisch und die Bezugnahme auf ta.id () ist nicht mehr eindeutig.