Ich habe eine harte Zeit mit einem gefürchteten Diamantenproblem. Zur Erinnerung, hier ist die klassische Klassenhierarchie dieses Problems:
%Vor%Um es zu lösen, besteht die Standardlösung darin, dass C1 und C2 virtuelle Vererbung verwenden, um von B zu übernehmen.
Mein Problem ist, dass B und C1 von einem SDK stammen, das ich nicht ändern kann. Beispiel unten, wo ich SubClassB nicht virtuell von Basis erben kann. Klassen: PureVirtualBase, Base und SubClassB stammen aus dem SDK, das ich verwende. Ich kann sie nicht ändern. SubClassA und Leaf sind meine benutzerdefinierten Klassen. Ich kann sie ändern.
%Vor%In einer solchen Situation, in der SubClassB nicht geändert werden kann, wird die virtuelle Vererbung von Basis verwendet. Wie sollte das so aussehen:
Irgendein Hinweis?
Weitere Informationen zum Beantworten von Kommentaren
Meine Zielarchitektur ist etwas komplexer als die Probe, die ich in der ursprünglichen Frage bereitgestellt habe:
%Vor%LeafOne: erbt von SubClassA und SubClassB (SDK)
LeafTwo: erbt von SubClassA und SubClassC (SDK)
LeafThree: erbt von SubClassA und SubClassD (SDK)
SubClassA ist mein eigener privater Code. Es bietet benutzerdefinierte Funktionen. Es sollte von SDK-Methoden wie eine Base-Instanz behandelt werden können. Diese Klasse wird nicht instanziiert, aber sie ist hier, um LeafOne, LeafTwo und LeafThree gleichzeitig behandeln zu können.
Dies weist auf ein Problem mit Ihrem Design hin, für das die einfachste Antwort ist, den Diamanten zu vermeiden. Ihre Auswahl an Namen für den Beispielcode ist schlimm genug, um es schwer zu machen, darüber nachzudenken, was Sie eigentlich tun möchten, aber überlegen Sie auf jeden Fall, ob Sie von beiden Eltern erben müssen und ob das macht Sinn.
Vererbung ist eines der am meisten missbrauchten Konstrukte in OO-Sprachen, es löst zwar ein Problem, wird aber als golden verwendet hammer überall sonst. Viele Male, was Sie in der Hand haben, ist ein Schraube , kein Nagel und das richtige Werkzeug ist kein Hammer.
Wenn Sie wirklich an diesen Designbeschränkungen festhalten, würde ich definitiv versuchen, von B direkt mit einer Klasse zu untergliedern, die C1 und C2 als zusammengesetzte Komponenten verwendet. Leider erfordert das manuelle Spiegeln der Benutzeroberfläche (hoffentlich ist es klein oder Sie können es auf das, was Sie benötigen, beschränken) und Proxy bis zu den Unterkomponenten. Es ist nicht schön, aber wenn Sie nicht etwas anderes auf dem Design durchsetzen können, dann haben Sie nicht wirklich viel Auswahl.
Ein Nachteil ist natürlich, dass Sie nicht die Typidentität haben, nach der Sie suchen (die Unterklasse wird nicht "isa" von C1 oder C2 erfüllen), was ausreichen könnte, um diesen Ansatz aus dem Wasser zu blasen.
Es ist nicht schön. Aber ich erwarte, dass es angesichts Ihrer Einschränkungen die "schlechteste" Lösung sein könnte.
Tags und Links c++ multiple-inheritance virtual-inheritance diamond-problem