Anfänger: Problem mit Functionpointern
-
Sers, also folgendes
Ich hab mir ein Tutorial zu Functionpointern durchgelesen (http://www.newty.de) und wollte mal sehn ob ich das richtig verstanden habe...aber wie's so is, scheitert man schonmal an der Eingangshürde.Also folgendes schwebt mir vor:
Ich möchte einer Klasse eine Methode dynamisch zuweisen. Das Prinzip ist dabei:
- definiere einen Typ für die Function
- definiere eine private Methode der Klasse welche von diesem Typ ist.
- definiere eine public Methode welche die Private Methode aufruft.
- definiere eine setter-Methode mit der man die Private Methode an eine beliebige Methode binden kann.Und so sieht das bei mir aus:
// deklaration of function pointer types typedef bool (*TClick_CallBack)(); class TglObject { //Baseobject for hirarchy of all ui-objects private: TClick_CallBack DoClick(); public: // Callbacksetters void SetOnClick(TClick_CallBack func) {&TglObject::DoClick = func;}; // Methods bool OnClick(); };Die Funktion SetOnClick is der Hacken. Nun wüßte ich gerne, wie ich die übergebne Function func so an DoClick binden kann, dass wenn ich DoClick aufrufe der Code ausgeführt wird, der in func defniert wurde. Ganz einfach...

-
Isses zu einfach oder zu schwehr? Ich für meinen Teil wüßt gern mehr!
PS: Poet auf Heimaturlaub.

-
Diese private Membervariable eh Funktion ist nicht das Wahre und afaik nicht funktionstüchtig. Sieh dir das hier mal an:
class Example { typedef bool (*Function) (); Function m_func; public: Example () : m_func(0) { } void callFunc () { if(m_func) m_func(); } void setFunc (Function func) { m_func = func; } };Jetzt kannst du jede Funktion mit der Signatur bool() zuweisen. Bei Methoden-Pointern wirds schwerer. Da musst du vorher die Klasse wissen bzw. ein Template anlegen:
template <class T> class Example { typedef bool (*Example::Method) (); Method m_method; public: Example (Method method) : m_method(method) { } bool myMethod () { return true; } }; // ok stupides beispiel... Example<Example> (&Example::myMethod);MfG SideWinder
-
Also mit Templates ... öhm ... Ich versteh gerade nicht so recht was das alles soll...
Wie muss ich meinen Code verändern, damit ich func zuweisen kann.
Nochmal der Code
// deklaration of function pointer types typedef bool (*TClick_CallBack)(); class TglObject { //Baseobject for hirarchy of all ui-objects private: TClick_CallBack DoClick(); public: // Callbacksetters void SetOnClick(TClick_CallBack func) {&TglObject::DoClick = func;}; // Methods bool OnClick(); };Bei SetOnClick sagt mir der Compiler: "non-lvalue in assignment" Keine Ahnung was das heißen soll.
-
Du kannst die Adresse einer Funktion nicht verändern... WTF soll das?
Guckst du hier -->
http://www.newty.de/fpt/index.html
-
Das Tutorial war das besagt, was ich schonmal gelsen hab...anscheinend aber nicht ausreichend durchdrungen.
Wie kann ich denn eine nichtstatische Memberfunction zur laufzeit umbiegen? Also ich will, dass beim aufruf von MeineKlasse.Draw eine Function aufgerufen wird, die ich der Klasse vorher mit MeineKlasse.SetDraw mitgeteilt habe.
Ich hoffe, wenn ich den passenden Code sehe versteh ich auch wieso es im moment nicht funktioniert. (Wobei ich durch den letzten Komentar schon ne Ahnung hab...)
-
// deklaration of function pointer types typedef bool (*TClick_CallBack)(); class TglObject { //Baseobject for hirarchy of all ui-objects private: //TClick_CallBack DoClick(); //soll das ne membervariable sein? TClick_CallBack DoClick; public: // Callbacksetters void SetOnClick(TClick_CallBack func) {DoClick = func;}; // Methods bool OnClick(); };Mir ist nicht wirklich klr, was du willst.
-
Ok ich erklärs nochmal genauer:
Ich möchte eine GUI schreiben. (Die Theorie dahinter ist kein Problem. Mit Delphi könnte ich das sicherlich einfach hinschreiben, aber es soll diesmal C++ werden.)
Für eine GUI ist es notwendig Buttons dynamische Ereignisbehandlungsroutinen zu zuweisen. Also der Instanz A eines Buttons möchte ich eindere Behandlungsmethode für OnClick Ereignisse zuweisen als der Instanz B.Meine Idee war der Klasse Button im private Teil einen Functionpointer zu geben, der auf die jeweilige Behandlungsroutine zeigt. Über einen öffentlichen Setter sollte man diesen Functionpointer setzen können. Und über eine öffentliche Methode z.B. OnClick() sollte der private Functionpointer aufgerufen werden.
Was bei mir momentan nicht geht, ist dem privaten Functionpointer DoClick die in Func übergebene Methode zu verpassen.
Ich hoffe meine Code-Versuche weiter oben sind jetzt verständlicher.
-
Das macht man normal so:
class button { protected: int posX, posY; // etc.... public: button(); virtual ~button(); virtual void onClick( /* ... */ ) = 0; virtual void onMouseOver( /* ... */ ) = 0; }; // dann leitet sich der benutzer einen eigenen button ab class myExitButton : public button { public: void onClick( /* ... */ ) { exit(0); } };
-
Also das macht man ganz bestimmt nicht so. Vererbung benutzt man um Klassenhierarchien aufzubauen, und nicht um Verschiedene Instanzen einer Klasse zu modifizieren.
Was soll ich den mit einer ExitButton Klasse. Da muss ich ja für jeden Button eine eigene Klasse ableiten, und die is dann ohne ende Spezialisiert auf diese eine Funktion.
Geht das was ich gefragt habe denn nicht in C++? Ohne irgendeinen Trick_17?
(Um mal nicht ganz so herablassend zu klingen. Exact das was du beschreibst habe ich in einem älteren Projekt gemacht. Was am ende rauskam entspricht nicht der Art Code die ich je wieder schreiben möchte. Wenn du eine umfangreiche GUI mit dieser Methode schreiben möchtest wirst du schnell merken, dass das nicht das wahre ist.
)----
Und die Sache mit "Den Functionpointer im Constructor übergeben" finde ich ... hmmm ... also wenns ne bessere Lösung gibt, wäre ich davon sehr angetan.
-
Man glaubt es kaum: http://www.antivoid.za.net/index.php/tutorials/functionpointers.php Kapitel "Callbacks"
-
Wird natürlich intressanter wenn du mal Callbacks auf Memberfunktionen machwn willst... Das hätte ich (und andere sicher auch) dir auch sagen können.
Du hast es ja selber gesagt:
- definiere eine setter-Methode mit der man die Private Methode an eine beliebige Methode binden kann.
Will mal sehen wie du das damit vereinbahrst.
Gruß
-
Hab mich vielleicht unklar ausgedrückt. Sorry.
Aber was ist der Unterschied zwischen dem Code in diesem Tutorial und dem von mir? Ich steh da momentan etwas ratlos da...
-
Jetzt gehts...Ich werd verrückt...Also...Aber das was gerade erfolgreich meinen Compiler passiert hat, war vor einigen Stunden noch falsch....glaub ich.
Naja Egal...jetzt gehts. Danke euch für eure Zeit. Sorry, für den Schmarn der zwischenzeitlich geschrieben wurde.
-
Aber das was gerade erfolgreich meinen Compiler passiert hat, war vor einigen Stunden noch falsch
Ganz bestimmt, dass wars :p
MfG SideWinder