Abstrakten Klassen erben
-
Hallo zusammen,
ich habe schon einige Einträge zum Thema ABC (abstract basis classes) gelesen,
aber irgendwie passt das ganze noch nicht so zu meinem Vorhaben.Nun zu meinem Problem:
Ich habe eine abstrakte Klasse A
class InterfaceA { public: std::string GetVersionOfA() = 0; }Dazu eine entsprechende Klasse A:
class A: public InterfaceA { public: std::string GetVersionOfA(); }Nun habe ich weiter eine abstrakte Klasse B:
class InterfaceB { public: std::string GetVersionOfB()=0; }Und eine dazugehörende Klasse B:
class B: public A, public InterfaceB { public: std::string GetVersionOfB(); }Wenn ich nun ein Objekt von der Klasse B erzeuge, kann ich leider nicht
aufGetVersionOfAzugreifen!
Was mache ich an dieser Stelle falsch?Besten Dank für eure Hilfe
Michael
-
Stichwort virtual:
//InterfaceA.h class InterfaceA { public: virtual std::string GetVersionOfA() = 0; };//InterfaceB.h class InterfaceB { public: virtual std::string GetVersionOfB() = 0; };
-
Das Zauberwort "virtual" hab ich natürlich schon verwendet, habs aber leider
in meinem Beispiel hier vergessen
Wenn ich nun ein Objekt von B erstelle, sehe ich alle Funktionen, die in InterfaceB definiert sind, aber keine aus InterfaceA. Es ist also so, wie ich
beschrieben habe, nach wie vor.Gruss
Michael
-
mmmhhhhh, wenn ich selber weiter darüber nachdenke, könnte der Fehler an einer anderen Stelle generiert werden. Daher erweitere ich jetzt Mal meine Ausführungen:
Die oben erwähnten Klassen habe ich in eine z.B. testCode.dll ausgelagert.
Anschliessend lade ich die Bibliothek ganz nach Anleitung von der msdn homepage.
Bis hier hin ist es auch kein Problem.Nach dem Laden benutze ich eine Factory-Function um ein Objekt B zu erstellen.
Dies sieht in etwas so aus:extern "C" __declspec (dllexport) InterfaceB* createB() { // call the constructor of the actual class InterfaceB *module = static_cast<InterfaceB*> (new B()); // return the created function; return module; };Hier scheint das Problem zu sein, da ich das neue Objekt auf ein InterfaceB caste, nehme ich Mal an.
Wie kann ich das nun ändern, oder was muss ich tun, dass InterfaceA trotzdem zugänglich ist. Ich kann nicht InterfaceB von InterfaceA ableiten.
Ich hoffe, jemand weiss Rat
Gruss und besten Dank im Voraus
Michael
-
Wenn du B als InterfaceB ansprichst, dann stehen dir auch nur die Methoden von InterfaceB zur Verfügung. Wenn du die Funktionen von A benötigst, musst du entweder nach A (oder InterfaceA) casten. Ansonsten wirst du wohl ein zusätzliches Interface benötigen. Muss B undbedingt von A erben? Vielleicht kann man auch A und B getrennt voneinander implementieren und in einem C zusammenfassen.
Greetz
-
In der Realität ist Klasse A eine Klasse für Single-Layer-Perceptrons und Klasse B entsprechend die Erweiterung für Multi-Layer-Perceptrons. Daher erscheint mir das Erben durchaus sinnvoll.
Ich denke da schon länger über ein anderes Interface nach, aber alles was ich teste, scheint an der Vererbung zu scheitern.
Kennst jemand einen Link oder so, der auf diese oder eine ähnliche Problematik eingeht?
Alle Links, die ich bisher gefunden haben, beschäftigen sich eher mit den Grundlagen der Vererbung und abstrakten Klassen.Danke schön
Michael
-
In der Realität ist Klasse A eine Klasse für Single-Layer-Perceptrons und Klasse B entsprechend die Erweiterung für Multi-Layer-Perceptrons. Daher erscheint mir das Erben durchaus sinnvoll.
Naja, so sinnvoll empfinde ich das nicht.
Das sie das gleiche Interface bereitstellen kann (wird vermutlich auch) ok sein. Jedoch dass der Multi Dings vom Single Dings die Impl. erbt denke ich macht nicht so sinn. Ev. sind zwei unabhängige Klasse besser, ev. mit Komposition die gemeinsame Teile der Impl. einbinden.Simon
-
Kann sein, dass ich noch etwas verpasst habe in der OOP-Programmierung.
Das Singel-Dings ist aber immer komplett in einem Multi-Dings
vorhanden.
Das Multi-Dings erweitert also einfach das Singel-Dings. Sollte man da nicht vererben ?Ich persönlich möchte definitiv kein Code an 2 stellen in der Software.
-
Singeldingens und Multidingens, isch klar

Naja ich weiß nicht wo dein Problem ist, denn wenn ich dein Programm Code nutze und in den jeweiligen Interfaces virtual benutze, kann ich, wenn ich ein Objekt von der Klasse B erstelle, Funktionen von Klasse A benutzen.
-
wie schon erwähnt, gehe ich davon aus, dass ich das Problem selber erzeuge, in dem ich zum einen den ganzen Code in einer dll habe und zum andern ein Objekt von B erzeuge mittels Factory-Function. Dazu verwende ich einen static_cast auf das InterfaceB ...
Leider habe ich bisher keinen anderen Weg gefunden. Daher denke ich zur Zeit nochmals über die Grundlagen der Vererbung nach. Bisher leider ohne Erfolg, die zündende Idee steckt noch irgendwo fest.
Die InterfaceA.h sowie die InterfaceB.h includiere ich in meinem Test-Programm.
Aber durch den static_cast werde ich wohl den Zugriff auf InterfaceA irgendwie unterbinden.
-
Der cast in deiner Factory Funktion ist sowiso unnötig.
Ausserdem würde ich bei solchen Dingen, wenn schon, dann den dynamic_cast verwenden (der wird nämlich zur runtime geprüft).
Simon
-
@Freaky,
Sein Problem ist, dass er von einemInterfaceBZeiger aus, auf Methoden vonA, bzw.InterfaceAzugreifen will. Die sind natürlich nicht bekannt, daInterfaceBweder vonAnoch vonInterfaceAerbt. Das typische Anfängerproblem
@schmidm6,
Von mir aus gesehen hast du den besten Hinweis, dass deine Vererbung falsch sein muss, denn der Code funktioniert so nicht. Wenn ein Objekt vonInterfaceBerbt, dann wissen wir nichts darüber, ob es auch vonInterfaceAoderAerbt.Wie theta es bereits gesagt hat, wäre womöglich eine Komposition besser. Zum Beispiel könntest du eine Instanz von
Ain die KlasseBsetzen und der Zugriff aufAkapseln.
Die is-a Beziehung ist eine extrem starke Bindung, man sollte diese nicht nur einsetzen, weil man einen Code nicht doppelt schreiben möchte. Für sowas kann man den Code selber in eine dritte Klasse oder freie Funktion auslagern.Wir kennen dein Design leider zu wenig, bzw. auch was dahinter steht. Ich habe keine Ahnung was dieses Single-Dings oder Multi-Dings sein soll

Daher ist es auch ein wenig schwer, dir beim Verbessern des Designs zu helfen.Grüssli
-
Hallo zusammen
Ich habe mich nun nochmals einige Zeit mit der OOP-Programmierung beschäftigt. Es sieht nicht so aus, als wäre ich geistig in der Lage, das ganze in der kurzen Zeit zu verarbeiten.
Ich habe nun meinen Code soweit angepasst, dass InterfaceB auch die Definitionen von InterfaceA enthällt. Die Klasse A erbt von InterfaceB
class A: public InterfaceB { ... }und die Klasse B erbt von A:
class B: public A ...soweit ist dies wohl nicht der eleganteste Weg, aber er funktioniert vorläufig und dann werde ich den Rest schon noch mal packen ...
Besten Dank bis dahin ...
Michael