Stellen Sie sich eine Standarddiamantvererbung vor. Klasse A definiert reine virtuelle Funktion fx, Klasse B definiert Implementierung für fx, Klassen C und D tun nichts mit fx. Wenn Sie versuchen, fx in Instanz der Klasse D aufzurufen, erhalten Sie den Fehler 'mehrdeutiger Funktionsaufruf', obwohl es nur eine Implementierung von fx gibt. Dies kann gelöst werden, indem B und C virtuell von A erben. Ist es eine richtige Lösung für das Problem? Wie genau verarbeitet die virtuelle Vererbung das Zusammenführen von virtuellen Funktionstabellen?
A --- & gt; B --- & gt; D
\ --- & gt; C ------ ^
... Anmerkung, Herb Sutter hat 3 ausgezeichnete Artikel über Mehrfachvererbung geschrieben (1) hier , (2) hier und (3) hier . Er schrieb eine ganze Reihe nützlicher Artikel im Guru der Woche hier . Sehr empfehlenswert ...
Erstens bin ich mir nicht sicher, ob ich deine Hierarchie richtig finde. Ich nehme an es ist so:
%Vor% Nun, D ist abstrakt, weil es zwei A
Unterobjekte in einem Objekt vom Typ D gibt: Eines, das durch B
durch das Gitter von B konkretisiert wird, und eines, das im durchlaufenden Gitter noch abstrakt ist %Code%. Ich nehme an, Sie haben einen Zeiger auf C
und versuchen, D
aufzurufen. Ja, es ergibt sich eine Mehrdeutigkeit, da der Compiler zwei Funktionen F
in zwei getrennten Gittern findet:
Sieht so aus:
%Vor%Sie können diese Situation formal beheben, indem Sie virtuell von A ableiten:
%Vor%Sie haben dann diese Situation, Diamantvererbung genannt:
%Vor% Bei der Suche wird festgestellt, dass F
überschrieben B::F
ist. Obwohl A::F
immer noch über A::F
erreicht werden kann, ist das keine Mehrdeutigkeit mehr, da D::C::A
virtuell geerbt wurde.
Ob das bei Ihrem speziellen Problem die richtige Lösung ist - das ist natürlich nicht sicher. Es gibt meistens bessere Möglichkeiten, als virtuelle von einer Klasse abzuleiten. Auf Ihre Frage zum Zusammenführen von virtuellen Funktionstabellen - das hängt vollständig von der Implementierung ab. A
wird, soweit ich weiß, einen Zeiger auf die eine A-Instanz in der virtuellen Tabelle von GCC
behalten, wenn wir virtuell ableiten.
Ist es eine richtige Lösung für das Problem?
Die "Diamond" -Vererbung ist problematisch, und die korrekte Erklärung der Lösung erfordert ein wenig Erklärung. Ich empfehle Ihnen, die folgenden Kapitel von Meyers Effective C ++ zu lesen:
Tags und Links c++ inheritance function virtual