Funktionszeiger in einer Klasse
-
Ich benutze Funktionszeiger um Callbackfunktionen zu progammieren. Die Callbackfunktion ist aber in einer Klasse. Wenn die beiden Funktionen nicht in einer Klasse definiert sind, dann lässt sich der Code fehlerfrei compilieren. Seit dem die beiden Funktionen aber ein Member einer Klasse sind, bekomme ich eine Fehlermeldung (2 mal):
error C2664: 'ausgabe' : Konvertierung des Parameters 1 von 'char (char)' in 'char (__cdecl *)(char)' nicht moeglich Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp uebereinDer Beispielcode:
#include "stdafx.h" class firstClass { public: char returnChar(char lChar) { return lChar; } }; class secondClass { public: char returnChar(char lChar) { return lChar; } void ausgabe2() { ausgabe(returnChar); } void ausgabe(char (*f)(char)) { cout << (*f)('r'); } }; int main(int argc, char* argv[]) { firstClass First; secondClass Second; printf("Hallo Welt!\n"); Second.ausgabe(First.returnChar); getchar(); return 0; }
-
Hier nochmal den Code, der fehlerfrei funktioniert:
#include "stdafx.h" char returnChar(char lChar) { return lChar; } void ausgabe(char (*f)(char)) { cout << (*f)('r'); } int main(int argc, char* argv[]) { printf("Hallo Welt!\n"); ausgabe(returnChar); getchar(); return 0; }
-
-
Sollte einen nicht überraschen. Um eine Memberfunktion ausführen zu können brauchst du ein Objekt.
Du übergibst aber nur die Adresse der Funktion, die kann der Compiler aber keinem Objekt eindeutig zuordnen und dann meckert er.Mögliche Lösungen:
- Funktions-Objekte
- Schnittstellen-Klasse von denen die betroffenen Klassen abzuleiten sind
- wie gehabt mit staischen Funktionen arbeiten
-
Ähnliches hab' ich mir auch geschrieben bzw. bin noch dabei. Ich bin dabei auf "Functors" gestoßen, was genau das war, was ich gesucht habe. Die Idee dahinter ist, dass Du eine Klasse schreibst, wo Du den operator() überschreibst. Wenn Du das ganze als Template-Klasse machst, dann kannst Du da denke ich viel mit anfangen, hier der Code (ungetestet):
template<class T> class MethodPtr { public: MethodPtr(T* _Object, void (T::* _Method)()) { this->Object = _Object; this->Method1 = _Method; } void operator()() { (*this->Object.*this->Method)(); } private: T* Object; void (T::* Method)(); };Aufrufen kannst Du das ganze dann so:
secondClass Second; MethodPtr mytest(&Second, &secondClass::returnChar); mytest();Ich muss die template-Parameter bei mir nicht weiter spezifizieren, da der Compiler (MinGW) die anscheinend automatisch erkennt, weiß aber nicht, ob das Standard-konform ist. Finde ich eigentlich eine ganz schöne Lösung und Du hast eine kleine Typsicherheit gegeben.
(Mutwillig kann man natürlich alles kaputt machen
)
-
@Matiz: Hm, so hab ich das auch schon woanders gesehen (CeGUI), aber ich hab da noch nicht richtig duirchgeblickt. Aber ich sage schonmal danke
@Mathias: Ich glaube, das ist nicht die Lösung...
@FireFlow: Werde ich mir mal angucken, wenn ich mal Zeit hab

-
Ja, das ist es. Ich muss wahrscheinlich nur den Operator auf
void operator()(char pChar) { (*this->Object.*this->Method)(pChar); }umschreiben...
-
@Timme
... was dann nichts anderes als ein Funktions-Operator ist wodurch das Objekt als Funktion ausführbar wird (Funktions-Objekt)....

-
@Mathias: Sorry, ich hab deinen Beitrag nicht genau gelesen. Hab nur die ersten Zeilen gelesen, hab mir aber danach gedacht, dass das mir nicht viel weiterhelfen wird. Und hab erstmal den Beitrag weiter unten gelesen.(Hatte nicht viel Zeit in der Freistunde) Jetzt im Nachhinein sehe ich, dass der Beitrag doch so einige Nützliche Informationen beinhaltet

@FireFlow: Das Tut ist ganz nützlich, hab ich mir vorhin schon ausgedruckt....