Kann man eine (Basis-)Klasse mittels `Plugin-Klasse` erweitern?
-
Hallo,
ich hantiere hier gerade etwas mit wxWidgets herum und bin recht neu in OOP. Jetzt bin ich bei folgendem allgemeinen Problem angekommen:Ich habe eine Basis-Klasse, zu der irgendeine Funktionalität hinzugefügt werden soll, damit auch alle abgeleiteten, bereits vorhandenen, Klassen darauf zugreifen können, so als wäre die neue Funktion schon in der alten Klasse vorhanden. Geht das ohne die Basis-Klasse zu verändern?
Ich stelle mir da sowas vor, wie eine Modul-/Plugin-Klasse, die man zur entsprechenden (Basis-)Klasse hinzuladen kann, um sie zu erweitern..
Wenn das garnicht geht, bleibt mir doch nur, außer im Quelltext rumzufummeln, dass ich jedesmal, wenn ich die neue Funktion brauche, sie jeweils zu den gewünschten Objekten direkt hinzufüge, statt einmal zur gemeinsamen Basis der Objekte, oder?!MfG,
Klon457
-
Der Sionn der Kapselung ist es ja die interna einer Klassendefinition zu verbergen. Sonst würde man dieses Konzept ad absuredum führen.
Was Du machen kannst ist halt eine freie Funktion zu defnieren, die einen Zeiger oder eine Referenz auf die fremde Basisklasse erwartet. Die kannst Du dann von allen Deinen abgeleiteten Klassen aufrufen.
class base { ... }; void myExtension( base *theObject, ... ) { } void myRefExtension( base &theObject, ... ) { } class derived : public base { void doit() { myExtension( this ); myRefExtension( *this ); } }
mfg Martin
-
Hallo, Danke für deine Antwort. Die Basisklasse zu übergeben ist mal nen Versuch wert. Würde mir zumindest viel 'Copy&Paste' erstparen, wenn ich das richtig verstehe.
Aber ich glaube, ich habe mich nicht deutlich ausgedrückt, denn an die internen Klassendefinitionen will ich nicht dran.. Zumindest nicht mehr, als jede abgeleitete Klasse auch! Ein Problem, das ich sehe (vielleicht weil ich das noch nicht alles überblicke) ist, dass es schon viele abgeleitete Klassen gibt, die ich aber ungerne weiter ableiten würde..
Also nochmal anders formuliert:
Ist es möglich zwischen Basis-Klasse und abgeleitete Klasse eine weitere einzufügen (bzw. an die Basis-Klasse anzuhängen), ohne dass die abgeleitete verändert werden muss?!
Wie war das denn nochml mit Freund-Klassen und der gleichen.. Das ist auch zufällig keine Lösung oder??
-
Klon457 schrieb:
Ist es möglich zwischen Basis-Klasse und abgeleitete Klasse eine weitere einzufügen (bzw. an die Basis-Klasse anzuhängen)
Klar geht das. Dann muss allerdings die abgeleitete Klasse von dieser "Zwischenklasse", die nun von der Basisklasse abgeleitet ist, abgeleitet werden, damit sie deren Eigenschaften erbt.
-
Klon457 schrieb:
Aber ich glaube, ich habe mich nicht deutlich ausgedrückt, denn an die internen Klassendefinitionen will ich nicht dran.. Zumindest nicht mehr, als jede abgeleitete Klasse auch! Ein Problem, das ich sehe (vielleicht weil ich das noch nicht alles überblicke) ist, dass es schon viele abgeleitete Klassen gibt, die ich aber ungerne weiter ableiten würde..
Was hällst Du davon, uns zu erklären, welches konkrete Problem Du gerade lösen willst.
mfg Martin
-
Schade, ich habs befürchtet. Jedenfalls Danke für die ernüchternden Infos.
-
mgaeckler schrieb:
Was hällst Du davon, uns zu erklären, welches konkrete Problem Du gerade lösen willst.
Das hier. Erklär mal, worum es konkret geht!
Derzeit ist das etwas rätselhaft. Du willst etwas zu einer Klasse hinzu fügen, aber diese Klasse nicht ändern. Warum nicht? Oder soll diese Änderung nur für abgeleitete Klassen gelten? Für alle? Für einzelne? Wenn für einzelne, warum nicht diese ändern? Wenn für alle, wo ist der Unterschied zum Ändern der Basisklasse? Oder soll das Ganze eventuell erst zur Laufzeit stattfinden?
Ich könnte jetzt alle möglichen Designs aufzählen, die irgendwie vage mit dem Problem zu tun haben, aber es wäre hilfreicher, genau zu wissen, was das Problem ist.
Bildchen malen oder Beispiele geben kann auch helfen.
-
Klar, gerne.
Soweit ich das richtig sehe, haben die Entwickler von wxWidgets in einer Basis-Klasse, von der sozusagen der Großteil von wxWidgets-Widgets abgeleitet ist, eine Funktion vergessen, oder wie auch immer - jedenfalls ist sie nicht da.
Und da hatte ich gehofft, ich könnte sie hinzufügen, ohne, dass ich am Quelltext der Basis-Klasse herumdoktern müsste, so dass sie dann in jedem abgeleiteten Objekt vorhanden ist, als wäre sie es schon immer gewesen...
-
Unglückliches Timing...
Hier noch bildlich:
Ich habe:
[] = Klasse
+,*,mod,min,max = Funktion[+ ] / | \ [mod] [min] [max] = = = [mod +] [min +] [max +]
Und möchte zur Basis "*" hinzufügen:
[+ ] & [* ] / | \ [mod] [min] [max] = = = [mod + *] [min + *] [max + *]
bzw.
[ + ] | [ * ] / | \ [mod] [min] [max] = = = [mod + *] [min + *] [max + *]
Kann man erkennen was ich meine?!...
-
Klon457 schrieb:
Unglückliches Timing...
Hier noch bildlich:
Ich habe:
[] = Klasse
+,*,mod,min,max = Funktion[+ ] / | \ [mod] [min] [max] = = = [mod +] [min +] [max +]
Und möchte zur Basis "*" hinzufügen:
[+ ] & [* ] / | \ [mod] [min] [max] = = = [mod + *] [min + *] [max + *]
bzw.
[ + ] | [ * ] / | \ [mod] [min] [max] = = = [mod + *] [min + *] [max + *]
Kann man erkennen was ich meine?!...
Wenn die Klassen mit mod, min und max von Dir sind, kannst Du zwischen den wxWidgets und Deinen eigenen Klassen natürlich noch eine neue Klasse einschieben. Du muß halt dann alle abgeleiteten Klassen von Dir entsprechend anpassen.
Wenn nicht muß Du meine Variante mit der Erweiterungsfunktion implentieren, die kannst Du dann aber auch von Deinen abgeleiteten Klassen aufrufen, so wie von mir beschrieben.mfg Martin
-
Anderer Ansatzpunkt: Ich würde mal vermuten, dass die Entwickler von wxWidgets wahrscheinlich besser wissen, warum sie was wie tun, als du. Vielleicht macht es Sinn, deine konkrete Problematik (nicht deinen Lösungsansatz!) hier oder in einem anderen wxWidgets-Forum zu beschreiben? Höchstwahrscheinlich übersiehst du eine ganz einfache Lösung innerhalb des Frameworks oder übersiehst einen wichtigen Grund, warum dein Ansatz nicht von vornherein so umgesetzt wurde.
-
@ mgaeckler:
Tja so einfach ist es leider nicht, aber ich werde deimen Rat folgen, denke ich..@SeppJ:
Ich hoffe sogar, dass sie besser wissen was sie tun. Das sagt aber erstmal nicht darüber aus, warum sie etwas nicht tun.
Solange sie nicht besser wissen, was ich tun soll, ist doch alles gut.
Ich will den Sachverhalt für dich etwas darlegen:
Es gibt wxWindow::GetTextExtent() um den Platzbedarf von gegebenem Text zu erhalten. Das funktioniert aber nur für Einzeiler. Hier kann man sich fragen, warum "\n" ignoriert wird, muss man aber nicht - wird schon seine Gründe haben, denke ich. Und wenn es nur Kompatibilitätsgründe sind...
Allerdings gibt es wxDC::GetTextExtent() mit selbiger Funktionalität und zusätzlich wxDC::GetMultiLineTextExtent() - eine Version für mehrzeiligen Text.
Ich finde, darum kann man es schon so sehen, dass das wxWindow-Pendant schlicht fehlt..
Sicherlich geht's auch anders, aber die Freiheit nehme ich mir.. Für das "Warum" siehe hier.Es könnte ja auch sein, dass sich die Entwickler gedacht haben, dass es zu trivial ist, aus der Einzeiler- eine Mehrzeilerversion zu machen und es daher dem Endanwender überlassen. Das sind aber nur Spekulationen, die auftreten, wenn man sich darüber Gedanken macht, warum etwas gerade nicht vorhanden ist..
Naja es wird schon nicht das letzte Mal gewesen sein, dass ich irgendwo nachträglich (unabhängig von wxWidgets) irgendeine Funktionalität hinzufügen möchte. Darum würde ich mgaecklers Tipp schon als hilfreich bezeichnen..
-
Klon457 schrieb:
Ich will den Sachverhalt für dich etwas darlegen:
Das musst du weder mir noch dem Rest des C++-Forums erklären, sondern im wxWidgets-Forum. Dem Thread dort zu folge musst du wohl "einfach nur das PaintEvent anzapfen", was immer das auch heißen mag. Ich hab von dem Framework keine Ahnung.
-
Viel deutlicher kann ich aber nicht erklären, worum es mir konkret geht - wie von dir verlangt. Ich dachte mir schon, dass es dich nicht wirklich interessiert. Aber das gleich "dem Rest des C++-Forums" anzudichten, finde ich schon etwas anmaßend von dir.. ..Zumindest hat der sog. Rest mir bislang sehr geholfen.
Wenn du mich an einen anderen meiner heutigen Beiträge erinnern musst, kann ich doch davon ausgehen, dass du auch meine Einwände dazu gelesen hast. Um so bezeichnender, dass du sie ignorierst..
Hast du etwas gegen mgaecklers Vorschlag? Der scheint doch des Rätsels Lösung zu sein.
-
Klon457 schrieb:
Viel deutlicher kann ich aber nicht erklären, worum es mir konkret geht - wie von dir verlangt. Ich dachte mir schon, dass es dich nicht wirklich interessiert. Aber das gleich "dem Rest des C++-Forums" anzudichten, finde ich schon etwas anmaßend von dir..
Weißt du was wirklich anmaßend ist? Anderen, die dir gerade eben noch geholfen haben, Nichtinteresse vorzuwerfen, bloß weil sie dich auf Dinge hinweisen, die du besser machen könntest. Bei diesem netten Ton ist es kein Wunder, dass dir - im passenderen WxWidgetsforum - auch nicht wirklich geholfen wurde.
-
Inwieweit hast du mir denn bei diesem allgemeinen Problem geholfen? Du sagst selbst, dass du im Speziellen keine Ahnung hast, willst mir aber dennoch erzählen wie ich es besser machen kann.
Und das selbst dann noch, nachdem man davon ausgehen kann, dass du den anderen Bitrag gelesen hast und von meinem eigens generierten Problem weißt.
Ich habe dein: "Das musst du weder mir noch dem Rest des C++-Forums erklären,(...)" , so verstanden, dass es dir im Grunde egal ist. Oder meinst du mit 'musst nicht', dass du mir freistellst was ich tue (nachdem ich es bereits getan habe und das auch noch auf deinen eigenen Wunsch hin)?! Es könnte ja sein, dass es doch den einen oder anderen Leser hier interessiert, meinst du nicht?Ob mir in diesem oder jenem Beitrag geholfen wurde oder nicht, kannst du ebenfalls beruhigt mir selbst überlassen - Scorcher24 hat doch dort im letzten Satz erklärt, dass mein Vorhaben so nicht geht, was hier auch mehfach von anderen Leuten bestätigt wurde. Zu den restlichen seiner Einwände habe ich mich ja bereits dort geäußert. Und, ich sage es nocheinmal, auch hier hat mir mgaeckler 1a geholfen. Das war eine direkte Lösung meines hier genannten Problems (naja so direkt wie in C++ eben möglich
) - eines, um es deutlich zu machen, C++-Problems und nicht eines wxWidgets-Problems, wie man auch an der Wahl des Subforums sehen kann.
Es wäre nett, wenn du anderen Leuten nicht wiederholt deine Meinung andichten würdest.
Deine Annahme, die Entwickler wüssten immer was sie täten, wird nicht von mir, sondern von den zahlreichen Bugtrackern und Foren, die dem Meinungsaustausch mit etlichen Entwicklern dienen, widerlegt.
Ich sag's mal so: Ich bin ja jetzt auch Entwickler, mit allem, was deiner Meinung nach daraus folgt...
Außerdem wüsste ich nicht, inwiefern dein Vorwurf mir gegenüber, meinen Vorwurf dir gegenüber relativieren können sollte.
-
Kinder, bitte den Ball flach halten.
Habe mir mal die Quellen von wxWidget reingezogen. So wie's ausschaut hätten die Entwickler tatsächlich Problemlos die gewünschte Funktion bereitstellen können.
sowohl wxWindow als auch wxDC benutzen nämlich eine interne Klasse wxTextMeasure, die die eigentliche Funktionalität betriebssystemabhängig implementiert.
diese Klasse stellt auch tatsächlich beie Funktionen zu Verfügung. Es wäre also ein leichtes gewesen, GetMultiLineTextExtent auch für wxWindow zu implementieren.
Wie dem auch sei, da zwischen wxWindow und Deinen eigenen Klassen noch andere wxKlassen liegen, kommst Du wohl nicht darum einen Funktion
GetMultiLineTextExtent( wxWindow *win, .... )
zu implementieren.
Wenn Du das sauber machen willst, muß Du dir halt ein wxDC Objekt aus dem Fenster erzeugen und davon dann GetMultiLineTextExtent aufrufen.
mfg Martin