Mit der regulären Mehrfachvererbung erhalten Sie mehrere Kopien von gemeinsamen Basisklassen. Wenn Sie eine Kopie wünschen, verwenden Sie die virtuelle Vererbung.
Gut erklärt in Wikipedia
%Vor%Wird Sie bekommen, was Sie erwartet haben
Wenn Sie auf diese Weise mehrere Vererbungen durchführen, erhalten Sie zwei Kopien der Großelternklasse. Dies ist das klassische gefürchteten Diamanten Problem, wo Sie versuchen, dies zu tun :
%Vor%Aber durch normale Vererbung bekommen Sie das tatsächlich:
%Vor%Also gibt es wirklich 2 Personen in einer Instanz der Fakultät, was bedeutet, dass Sie 2 Namen bekommen.
Um den Diamanten in der ersten Abbildung oben zu erhalten, möchten Sie virtuell verwenden Vererbung .
%Vor%Sie erben von den zwei verschiedenen Klassen separat.
Sie sollten virtuelle Vererbung
verwenden Sie sind auf das klassische Problem der Diamantvererbung gestoßen. Aufgrund der Art der Mehrfachvererbung in C ++ gibt es tatsächlich zwei verschiedene Kopien von name
in Faculty
. Dies kann normalerweise durch Verwendung virtueller Vererbung wie folgt gelöst werden, sodass Sie nur eine Instanz von Person
und seine Mitglieder haben:
Ich bin mir in diesem Fall ziemlich sicher, aber Sie wollen das nicht tun. Es scheint nicht vernünftig anzunehmen, dass jedes Faculty
auch ein Student
UND ein Staff
Mitglied ist, also sollten Sie es nicht auf diese Weise darstellen. Es erscheint plausibel, dass ein Faculty
immer ein Staff
wäre, also könnten Sie eine einzelne Vererbung verwenden, um diese Beziehung zu modellieren. Dann, wenn nötig, faktorieren Sie (in freie Funktionen oder eine separate Klasse) den gemeinsamen Code vom Schüler, der auch in Faculty
benötigt wird.
class Faculty
erbt zwei Unterobjekte von class Person
, eins bis class Student
und ein anderes bis class Staff
.
&faculty.Staff::name
liefert die Adresse des Unterobjekts von class Person
, abgeleitet von class Staff
.
&faculty.Student::name
liefert die Adresse des Unterobjekts von class Person
, abgeleitet von class Student
.
Beide sind verschiedene Unterobjekte und daher die unterschiedliche Adresse.
Bei Mehrfachvererbung hat Ihre abgeleitete Klasse faculty
2 Kopien von Person
. 1. bis Student
und 2. bis Staff
.
Wenn Sie faculty.Person::name
referenzieren, bezieht sich das entweder auf Student
oder auf Staff
. Dies ist eine mehrdeutige Situation und wird sogar nicht mit g ++ kompiliert.
In MSVC scheint es, dass, da Faculty
zuerst Student
und dann Staff
erbt, es sich um faculty.Person::name
als facutlty ==> Student ==> Person ==> name
handelt. Deshalb sind die ersten 2 Zeilen gleich und die dritte Zeile ist anders.
Ein bisschen abseits vom Thema aber .... Die meisten erfahrenen Entwickler vermeiden Mehrfachvererbung. Es ist schwer aufrechtzuerhalten und voller Gefahr.
Tags und Links c++ inheritance multiple-inheritance diamond-problem