Frage zur Multi-Vererbung in C ++?

8

Ich habe den folgenden Code:

%Vor%

Wenn es ausgeführt wird, gibt das Programm die Ergebnisse aus:

%Vor%

Ich verstehe es nicht. Warum unterscheidet sich die Adresse in Line 1 und Line 2 von Line 3 , während sowohl Student als auch Staff den Namen von Person erben?

    
ipkiss 18.05.2011, 11:43
quelle

7 Antworten

9

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

    
Lou Franco 18.05.2011, 11:49
quelle
13

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%     
Doug T. 18.05.2011 11:50
quelle
2

Sie erben von den zwei verschiedenen Klassen separat.

Sie sollten virtuelle Vererbung

verwenden     
sergio 18.05.2011 11:49
quelle
1

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:

%Vor%

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.

    
Mark B 18.05.2011 13:30
quelle
0

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.

    
Alok Save 18.05.2011 11:48
quelle
0

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.

    
iammilind 18.05.2011 12:00
quelle
0

Ein bisschen abseits vom Thema aber .... Die meisten erfahrenen Entwickler vermeiden Mehrfachvererbung. Es ist schwer aufrechtzuerhalten und voller Gefahr.

    
Steve Wellens 18.05.2011 12:03
quelle