Klassenfrage :)
-
@omggg
Um etwas genauer zu sein:
Es gibt die Klasse Display mit Methoden um in den FB zu Zeichnen und zu Schreiben. Ausschließlich ein Objekt dieser Klasse wird einem Objkt klasse ui_interface übergeben das sich selbst darüber darstellt. Das Objekt der Klasse ui_interface wird einem Objekt der Klasse Apple Übergeben das die berechnung der Mandelbrodtmenge durchführt und diese über die Methode "ui_interface->diplay->putPixel" darstellt. Die Parameter der Berechnung ist das Objekt ui_interface. Und auch die Buttons sind in ui_iterface. Dort genau komme ich nicht weiter, eine Apple->Methode aufrufen wenn in ui-interface::onMouseOver x und y passen. (Die Mausfunktion ist nicht das Problem sondern der Methodenaufruf)
-
@SeppJ
Danke für die Antwort, aber ich steige leider nicht dahinter was die Definition von Caller bedeuted. Wie du selbst schon andeutest ist das ziemlich umständlich.
-
Ist nur ein Beispiel für die beiden Modi, die ich erklärt habe:
unbound_foo_member
ist ein Zeiger auf eine Methode der anderen KlasseFoo
und der Nutzer dieses Zeigers muss selber irgendwo ein Foo-Objekt herbekommen (hier erstellt der Caller dafür das Objekt mit i=123)bound_member
ist ein allgemeiner Zeiger auf eine beliebige Funktion (mit der passenden Signatur), und man hat ihm hier ein funktionsartiges Objekt zugewiesen, das den Aufruf an das Foo-Objekt (i=456) aus der main koppelt. Man kann dem gar nicht mehr ansehen, dass das irgendwie mit Foo zu tun hat, es ist nicht unterscheidbar von einem normalen Funktionszeiger (außer dass der Typ dahinter irgendetwas wildes ist)
Dass ich das in die Klasse
Caller
verpackt habe, kommt wegen deiner Fragestellung, dass du das unbedingt einer Klasseninstanz übergeben wolltest. Das Prinzip ist aber völlig unabhängig davon, wie man es benutzt.void (Foo::*)(void)
mag zwar kompliziert aussehen, aber ist auch nur ein Typ wie jeder andere Variablentyp und nutzt sich genauso wieint
.Ich möchte aber nochmals betonen, dass das äußerst ungewöhnlich ist, so viel (oder überhaupt irgendetwas) in C++ mit Memberfunktionszeigern machen zu wollen, und du dein Design nochmal überdenken solltest. In C kann ich das ja noch sehen (und da sind es ja auch keine richtigen Memberfunktionen), um so etwas wie virtuelle Funktionen zu emulieren. Ist es vielleicht das, was du wirklich willst? Virtuelle Funktionen? Und hast noch nicht davon gehört weil du neu in C++ bist?
omggg ist unser örtlicher Dauertroll. Ich würde an deiner Stelle dessen Beiträge einfach komplett ignorieren.
-
@SeppJ
Haha, immerhin half mir der Troll meine Frage etwas zu konkretisieren.
Ich meine: Ist es möglich Apple->schrumpf() aus Apple->Wurm->friss() aufzurufen? und, würdest du bitte eine der beiden Möglichkeiten nochmals isoliert für mich dartellen, wenn nicht gar die Antwort auf die Frage?
Ich verstehe vor allem die Definition Von Caller(...) unter public nicht
-
@EL-europ
Ich bin kein Programm, aber @SeppJ mag mich nicht, deshalb schreibt er oder sie das.Auf deine Fragen kann ich zurzeit aber nicht näher eingehen.
-
@omggg
ok, danke
-
@SeppJ Ichversuch mal deinen Code zu beschreiben
in der Klasse Caller
wird mit "void (foo.." ein Zeigerobjekt auf irgendeine Methode der Klasse Foo angelegt,
und mit "std::func.."eine std::function mit dem namen "bound_member" und dem Rückgabewert void deklariert.
Dann unter public folgt der Konstruktor von Caller dem zwei Parameter und dazu zwei ppassende Standartwerte übregeben werden? Und in der Methode call() wird "einfach" auf den Konstruktor von Foo zugegriffen um dann über das Objekt f.*unbound_foo_member auf eine in den Konstrutionsparametern übergebene Funktion in Foo zugreifen zu können und dann wird die std::function bound_member aufgerufen.Wenn das stimmt ist das mir zu Abtrakt um es auf Apfel und Wurm übertragen zu können.
Kannst du bitte den Konstruktor von Caller( wenn es den überhaupt einer ist) und die "Schritte" in main näher erläutern
-
Da, ganz ohne drumherum.
#include <iostream> #include <functional> using namespace std; class Foo { int i; public: Foo(int i) : i(i) {} void func1() { std::cout << "Func 1 von Foo(i=" << i << ")\n"; } }; int main() { Foo f(456); std::function<void()> bound_func1 = [&f] {f.func1(); }; void (Foo::* unbound_func1)() = &Foo::func1; bound_func1(); (f.*unbound_func1)(); }
Den Caller hatte ich doch nur gezeigt, weil du dich so daran aufgehangen hattest, dass das unbedingt in einer Klasse sein müsse, als ob da dran irgendetwas besonderes wäre.
-
@SeppJ
Ich hab eine einfache Frage ja auch kompliziert gestellt, und versuch jetzt erstmal die Übertragung deines Codes
-
@EL-europ sagte in Klassenfrage :
@SeppJ
Ich hab eine einfache Frage ja auch kompliziert gestellt, und versuch jetzt erstmal die Übertragung deines CodesNein! Werd' lieber dein Design los, das dich denken lässt, dass dies überhaupt nötig wäre! Du übersiehst garantiert irgendwas simples, das schon in der Sprache eingebaut ist. Dazu musst du natürlich erst einmal die Sprache besser lernen. Aber das wäre was gutes, denn man sollte schließlich die Sprache beherrschen, die man spricht.
-
@SeppJ
Mir fällt nix besseres ein. Ich müsste ja eigentlich eine "abstrakte" Klasse definieren von der ich Apfel und Wurm gemeinsam ableite; Wenn ich den oop-ansatz richtig verstehe?
-
@EL-europ sagte in Klassenfrage :
@SeppJ
Mir fällt nix besseres ein. Ich müsste ja eigentlich eine "abstrakte" Klasse definieren von der ich Apfel und Wurm gemeinsam ableite; Wenn ich den oop-ansatz richtig verstehe?Da wird ja gerade der Designfehler sein, denn das klingt offensichtlich falsch. Aber mit dem Apfel-Wurm-Beispiels kommt man da nicht weiter, weil da in der echten Welt keine tiefergehenden Beziehungen existieren, als das beides physikalische Objekte sind, und das ein Apfel einen oder mehr Würmer haben kann. In der echten Welt wird der Apfel nie etwas mit einem Wurm machen, und die Würmer werden eventuell etwas aus dem umgebenden Apfel fressen. Nichts davon klingt auch nur entfernt nach Übergabe von Memberfunktionszeigern..
-
@SeppJ Nun ja aber:
Die Beziehung "Apfel->schrumpf() wenn Apfel->Wurm->friss()" ist gegeben.
Aber du hast Recht, ich sollte zumindest die entsprechenden Kapitel noch mal lesen. Bis dahin
-
Ist ein bisschen komisch, dass der Apfel sich von dem Wurm fressen lässt, aber naja, nehmen wir das mal als gegeben an, weil die Analogie vielleicht nicht perfekt ist. Aber wieso muss in dem Fall an
Wurm::friss
die MethodeApfel::schrumpf
übergeben werden? Sollte nicht die Fressmethode wissen, dass sie den Apfel schrumpfen soll?class Wurm { void friss(Apfel &zu_fressender_apfel) { ... zu_fressender_apfel.schrumpf(); ... } };
Oder ist die Sache, dass der Wurm auch in anderem Obst sein kann? Dann wäre das, wie spekuliert, ein Fall für virtuelle Methoden:
class Obst { virtual void schrumpf(); }; class Apfel: public Obst { virtual void schrumpf() {wie ein Apfel schrumpft;} }; class Birne: public Obst { virtual void schrumpf() {wie eine Birne schrumpft;} }; class Wurm { void friss(Obst &zu_fressendes_obst) { ... zu_fressendes_obst.schrumpf(); ... } };
Da wird dann in
friss
automatisch an die passendeschrumpf
-Methode verwiesen, je nachdem, welches Obst der Wurm frisst.Im Hintergrund arbeiten dann zugegebenermaßen Memberfunktionszeiger. Aber das macht halt die Sprache für dich als Feature, und du musst dich nicht mit solch fehleranfälligem Zeug mit komischer Syntax herumschlagen. In C muss man das halt selber machen, wenn man diesen Effekt will, daher hatte ich die Vermutung, dass das hier die Richtung ist, aus der du kommst.
-
Danke @SeppJ
Ich habs über std::function hinbekommen die Methode aufzurufen, jetzt kann ich den restlichen Code erstma debuggen
-
@EL-europ sagte in Klassenfrage : ):
Und werde die entsprechenden Kapitel in Jürgen Wolf's c++11 lesen. Oder gibt es eine Onlninefom die vielleicht sogar besser ist.
Herr Wolf ist in diesem Buch immer sehr theoretisch mit seinen Beispielen.Du hast den schlechtesten Autor für C++ erwischt: WARNUNG: Bücher von Jürgen Wolf zu C und C++ zum Lernen ungeeignet weil....
Wenn du englisch beherrschst, dann verwende LearnCpp.
-
Ojeh, das hatte ich ganz überlesen. Das erklärt die komisch klingenden Designprobleme. Laut Jürgen Wolfs Designbeispielen ist ein Supermarkt schließlich ein Wurstbrot. Nein, das ist kein Scherz.
-
@Th69 Danke für den Link
-
@SeppJ @Th69
Ich glaube Herrn Wolf fehlte damals (als er die Bücher schrieb) einfach die Praxis, also nicht "Programmierpraxis" sondern Berufspraxis. Seine Beispiele lesesn sich wie von einem Schüler dessen Lebensmittelpunkt die Schule ist. Es sind seit dem "c++11" schon Jahre vergangen, und zu hoffen das Jürgen Wolf seine Prxis erweitert hat und in Bücher einbringen wird ist berechtigt.
-
Hm, nur weil in einem Beispiel ein Supermarkt ein Wurstbrot ist... sollte man ihm vielleicht nicht jegliche Fähigkeiten absprechen, geradeaus zu denken... Denn das Supermarktbeispiel ist total irrelevant... wichtig sind die Paradigmen.