7
votes

C ++: Les fonctions de membre de la classe comme des rappels événementiels

J'essaie d'ajouter un système de messagerie simple à mon projet, où des événements peuvent être invoqués par une fonction, qui conduira à tous les rappels enregistrés à cet événement appelé.

Maintenant, le moyen logique de le faire consiste à utiliser des pointeurs de fonction. Il serait facilement possible de transmettre le pointeur à la fonction de rappel souhaitée au gestionnaire d'événements, pour vous inscrire. Une fonction de rappel d'événements renvoiait toujours un int et prenez un vide * comme argument.

Cependant, je ne veux pas enregistrer des fonctions globales statiques comme des rappels d'événement - j'aimerais le faire avec Fonctions membres de la classe . .

  • est-il même possible d'accomplir cela avec C ++? Stocker et appeler des pointeurs aux fonctions des membres de différentes classes mais avec le même en-tête de la même fonction .

  • Si cela n'est pas possible, avez-vous des suggestions sur la façon dont je pouvais travailler autour de cela? J'aimerais vraiment ajouter des auditeurs d'événements directement à mes cours.


1 commentaires

Faire des efforts pour éviter le vide *. Il n'est généralement pas nécessaire en C ++ et il ouvre des possibilités d'erreurs étranges dans des systèmes plus complexes: il oblige la cohérence entre l'expéditeur et le récepteur sans l'aide du compilateur.


7 Réponses :


0
votes

Non, ce n'est pas possible (sauf si vous ne le faites pas C ++ / CLI avec .NET).

Maintenant, vous pouvez toujours créer des fonctions statiques, les transmettre à un objet sous forme de paramètre et la seule chose qu'ils feront est d'appeler votre fonction de membre sur cet objet. (En fait, une distribution sera nécessaire d'abord).


0 commentaires

3
votes

Bien sûr que c'est possible! Jetez un coup d'œil à boost.signal2 et boost.bind .

Boost.Signal2 implémente essentiellement un système de signal et de machines à sous, ce dont vous avez besoin exactement. Ensuite, vous pouvez utiliser boost :: lid qui est une généralisation de std :: bind1st et std :: bind2nd pour obtenir des wrappers d'objet de fonction à Fondamentalement, tout ce que vous pouvez penser (dans votre cas, méthodes membres). C'est vraiment puissant.

Voir cet officiel Boost Tutoriel .


0 commentaires

0
votes

Le plus proche que j'ai géré est d'enregistrer une fonction de membre statique comme rappel. L'élément statique prend l'objet (ceci) le pointeur comme argument en plus des arguments envoyés par le gestionnaire d'événements et l'utilise pour appeler la fonction membre. XXX

Enregistrement MyClass :: Callback et ceci avec votre gestionnaire. Vous devrez peut-être envelopper cela dans la structure des références argolant si vous êtes restreint dans ce qui peut être retourné.


0 commentaires

1
votes

Je ne suis pas complètement sûr de ce que vous voulez archiver, mais vous devriez peut-être regarder SOIGNAL SIGNALS2

Il est assez utile si vous souhaitez créer une sorte de mécanisme de signal / emplacement.


0 commentaires


2
votes

Voici ma tentative pas si bonne pour faire un travail comme celui-là: Tout d'abord, vous avez besoin d'une classe de manutention d'événement de base, appelons-le Evthandler pour l'instant:

ShutdownMessageCenter message_center;
EvtHandler * some_handler = new EvtHandler ();
Foo * some_foo = new Foo ();
message_center.register (some_handler, &EvtHandler::handleEvent);
message_center.register (some_foo, static_cast<void (EvtHandler::*)(Event &)>(&Foo::handleFooEvent);
message_center.callListeners ();


0 commentaires

0
votes

J'utilise Lukes Réponse avec Swig, car Swig ne prend pas en charge toutes les caractéristiques C ++ 11 ... Cela peut probablement être amélioré encore plus avec l'approche de Parsa Jamshidis.

Je l'ai modifiée pour couvrir encore plus de cas (quantité variable d'arguments et de type de retour variable): xxx


0 commentaires