Diamantvererbung und rein virtuelle Funktionen

7

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 ------ ^

    
Brian Tompsett - 汤莱恩 19.01.2009, 13:46
quelle

2 Antworten

19

... 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:

%Vor%

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.

    
Johannes Schaub - litb 19.01.2009 14:02
quelle
3
  

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:

  • Punkt 26, Wachen Sie gegen mögliche Mehrdeutigkeiten
  • Punkt 43, Verwenden Sie mehrfache Vererbung mit Bedacht .
ChrisW 19.01.2009 13:58
quelle

Tags und Links