Über das Speicherlayout
Nebenbei bemerkt, das Problem mit dem gefürchteten Diamanten ist, dass die Basisklasse mehrfach vorhanden ist. So mit regelmäßigen Vererbung, glauben Sie, Sie haben:
A
/ \
B C
\ /
D
Aber im Speicherlayout haben Sie das:
A A
| |
B C
\ /
D
Dies erklärt, warum beim Aufruf von D::foo()
haben Sie ein Zweideutigkeitsproblem. Aber die real Das Problem tritt auf, wenn Sie eine Mitgliedsvariable von A
. Nehmen wir zum Beispiel an, wir haben:
class A
{
public :
foo() ;
int m_iValue ;
} ;
Wenn Sie versuchen, auf die m_iValue
de D
wird der Compiler protestieren, denn er sieht in der Hierarchie zwei m_iValue
nicht eine. Und wenn Sie einen ändern, sagen wir, B::m_iValue
(das ist die A::m_iValue
Elternteil von B
), C::m_iValue
nicht geändert werden (das ist die A::m_iValue
Elternteil von C
).
Hier kommt die virtuelle Vererbung ins Spiel, denn damit erhalten Sie wieder ein echtes Rautenlayout, bei dem nicht nur ein foo()
Methode, sondern auch eine und nur eine m_iValue
.
Was kann schon schiefgehen?
Stellen Sie sich vor:
A
hat einige grundlegende Funktionen.
B
fügt eine Art cooles Array von Daten hinzu (zum Beispiel)
C
ein cooles Feature wie ein Beobachtermuster hinzufügt (z. B. bei m_iValue
).
D
erbt von B
y C
und damit von A
.
Bei normaler Vererbung ist die Änderung von m_iValue
de D
ist zweideutig, und dies muss geklärt werden. Selbst wenn dies der Fall ist, gibt es zwei m_iValues
innerhalb D
Sie sollten also daran denken und beide gleichzeitig aktualisieren.
Bei der virtuellen Vererbung wird die Änderung m_iValue
de D
ist ok... Aber... Nehmen wir an, Sie haben D
. Durch seine C
Schnittstelle haben Sie einen Beobachter angehängt. Und durch seine B
Schnittstelle aktualisieren Sie das coole Array, was den Nebeneffekt hat, dass Sie direkt die m_iValue
...
Da die Veränderung der m_iValue
direkt erfolgt (ohne Verwendung einer virtuellen Accessor-Methode), "hört" der Beobachter durch C
wird nicht aufgerufen, da der Code, der das Abhören implementiert, in C
y B
weiß nichts davon...
Schlussfolgerung
Wenn Sie einen Diamanten in Ihrer Hierarchie haben, bedeutet das, dass Sie mit 95%iger Wahrscheinlichkeit etwas in dieser Hierarchie falsch gemacht haben.