Pointer auf Memberfunktionen
-
Hallo Leute
Könnt ihr mir sagen, wie man sowas in C++ realisiert ?? Mir ist klar, dass das Beispiel unten nicht funktionieren kann, doch denke ich, dass daraus meine Absicht bekannt wird !#include <iostream> class Keyboard{ public: void (*onKeyDown)(int key); void getDeviceState(void); }; void Keyboard::getDeviceState(){ this->onKeyDown(4); } class Game{ public: void onKeyDown(int key); }; void Game::onKeyDown(int key){ std::cout << "cool"; } int main(){ Game game; Keyboard keyboard; keyboard.onKeyDown = &game.onKeyDown; keyboard.getDeviceState(); return 0; }
Mit freundlichen Grüssen Ishildur
-
und wieso machst du nicht eine basisklasse, leitest dann deine gewünschte klasse davon ab und übergibst dann einen pointer auf die "wunsch klasse" ?
wozu einzelne funktionen übergeben, sowas ist meißtens nicht nötig.
rapso->greets();
-
@rapso
Ich verstehe nicht ganz, was du meinst ??
-
#include <iostream> class Keyboard{ public: void onKeyDown(int key); void getDeviceState(void); }; void Keyboard::getDeviceState(){ onKeyDown(4); //this ist unnötig, kannst auch noch ein paar mal nach Keyboard casten, das bringt nichts } class Game : public Keyboard{ public: void onKeyDown(int key); }; void Game::onKeyDown(int key){ std::cout << "cool"; } int main(){ Game game; Keyboard* keyboard; keyboard = &game; keyboard.getDeviceState(); return 0; }
rapso->greets();
-
Achtung, Leaks, nur zur Anschauung:
#include <iostream> class IEventHandler { public: virtual void Raise(int n) = 0; }; template <class T> class KeyboardEventHandler : public IEventHandler { public: KeyboardEventHandler(T& t) : myt(t) { onKeyDown = &T::onKeyDown; } void(T::*onKeyDown)(int key); void Raise(int n) { (myt.*onKeyDown)(n); } T& myt; }; class Keyboard{ public: IEventHandler* pKeyboardEventHandler; void getDeviceState(void); }; void Keyboard::getDeviceState(){ pKeyboardEventHandler->Raise(4); } class Game{ public: void onKeyDown(int key); }; void Game::onKeyDown(int key){ std::cout << "cool"; } int main(){ Game game; Keyboard keyboard; keyboard.pKeyboardEventHandler = new KeyboardEventHandler<Game>(game); keyboard.getDeviceState(); return 0; }
-
Ok, das wäre eine alternative! Allerdings interessiert mich die Technik, mit welcher die Delphi - Events realisiert wurden, so was muss doch in C++ auch möglich sein ?
Kennst du Delphi ??
Man hat z.B. eine Datenbank Klasse und eine Programmklasse. Die Programmklasse implementiert die Datenbank Klasse als Member. Wenn die Datenbank disconnected löst sie einen Event aus, sprich sie ruft einen Pointer auf eine Methode in der Art "onDisconnect" aus, welche dann auf eine Methode in der Programmklasse zeigt...
-
und was trifft dabei nicht auf mein beispiel zu?
bei deplhi mußt du die unit dazupacken und hier halt die klasse
du leitest ab und überlädst die funktionen von denen du das event fangen möchtest, der rest ist in der basisklasse und übernimmt das eventhandling
ich seh den unterschied nicht...
rapso->greets();
-
Um das geht es doch gar nicht! Mich interessiert einfach, wie die Entwickler des Delphi Framework das realisert haben...
Hast du denn keine Idee ??
-
dann kenn ich deplhi wohl nicht gut genug um den unterschied zu sehen in den jeweiligen frameworks. ich hätte gedacht dass mein vorschlag das macht, was OOP anbietet :-S
rapso->greets();
-
Ich versuch noch mal mit einem anderen Beispiel zu beschreiben, was ich tun möchte...
#include <iostream> class Figure{ public: int i; // weis doch auch nicht }; class Tetris{ private: void(*onImpact)(Figure *pFig); // methode die Aufgerufen werden soll, wenn ein Stein irgendwo aufschlägt public: void update(void); void setOnImpactAction(void (*onImpact)(Figure *pFig)); // methode für Aufschlag definieren, zur Laufzeit jederzeit änderbar }; void Tetris::setOnImpactAction(void (*onImpact)(Figure *pFig)){ this->onImpact = onImpact; } class Game{ private: void impactAction(Figure *pFig); // in dieser methode wird definiert, was passieren soll, wenn ein Stein in einer beliebigen Tetris Klasse irgendwo aufschlägt Tetris ts; // Instanz der Tetrisklasse public: // konstruktor und destruktor Game(void); ~Game(void){} void update(void); // spiel updaten, wird bei jedem Frame aufgerufen }; Game::Game(void){ this->ts.setOnImpactAction(&this->impactAction); } Game::update(void){ this->ts.update(); } void Game::impactAction(Figure *pFig){ std::cout << pFig->i; }
-
Delphi-Events kenne ich nicht, aber vielleicht meinst du so etwas wie boost-signal:
http://www.boost.org/doc/html/signals.html
So ein Signal packst du in deine Klasse Keyboard. In der main-Funktion meldest du dann das Game beim Keyboard an und später, wenn du möchtest, dass das Signal alle angemeldeten Funktionen aufruft, rufst du den operator() des Signals auf:
(Nur Beispielcode, funktioniert nicht !!)
#include <iostream> class Keyboard{ public: void getDeviceState(void); signal1<void,int> keyDownSignal; }; void Keyboard::getDeviceState(){ keyDownSignal(4); } class Game{ public: void onKeyDown(int key); }; void Game::onKeyDown(int key){ std::cout << "cool"; } int main(){ Game game; Keyboard keyboard; keyboard.keyDownSignal.connect(&Game::onKeyDown,&game); keyboard.getDeviceState(); return 0; }
Das Ganze kommt dann ohne Zusatzklassen wie KeyboardEventHandler aus, game muss nur eine kompatible onKeyDown-Funktion haben.