C ++: class functions as event calls

I am trying to add to my project a simple messaging system in which events can be called by a function, which will lead to all callbacks registered for the called event.

Now the logical way to do this is to use function pointers. It would be easy to pass a pointer to the desired callback function for the event manager to register. The event callback function always returns intand accepts an argument void*.

However, I do not want to register static global functions as my event callbacks - I would like to do this using class functions .

  • Is it possible to accomplish this with C ++? Saving and calling pointers to member functions of different classes , but with the same function header .

  • If this is not possible, do you have any suggestions on how I can get around this? I would really like to add event listeners directly to my classes.

+5
source share
6 answers

Yes it is possible. C ++ 0x has a class functionthat handles this , while others indicate that Boost has similar capabilities.

You can also use your own, but the syntax is not for the faint of heart:

#include <iostream>

class Callable
{
    public:

        virtual ~Callable() {}
        virtual int operator() (void* args) = 0;
};

class CallableFreeFunction  : public Callable
{
    public:

        CallableFreeFunction(int (*func)(void*)) : func_(func) {}

        virtual int operator() (void* args) { return (*func_)(args); }

    private:

        int (*func_)(void*);
};

template <typename tClass>
class ClassMemberCallable : public Callable
{
    public:

        ClassMemberCallable(tClass* instance, int (tClass::*memberfunction)(void*)) : instance_(instance), memberfunc_(memberfunction) {}

        virtual int operator() (void* args) { return (instance_->*memberfunc_)(args); }

    private:

        tClass* instance_;
        int (tClass::*memberfunc_)(void*);
};

class Foo
{
    public:

        int derp(void* args)
        {
            std::cout << args << '\n';
            return 2;
        }
};

int freefunctionfoo(void* args)
{
    std::cout << "free" << args << '\n';
    return 2;
}

int main(int argc, char* argv[])
{
    Foo myfoo;

    Callable* callable = new ClassMemberCallable<Foo>(&myfoo, &Foo::derp);

    (*callable)(0);

    delete callable;

    callable = new CallableFreeFunction(freefunctionfoo);

    (*callable)(0);

    delete callable;

    std::cin.get();

    return 0;
}

, - . , . :

http://www.newty.de/fpt/index.html

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

:

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

+6

, ! Boost.Signal2 Boost.Bind.

Boost.Signal2 , , . boost::bind, std::bind1st std::bind2nd, , ( , -). .

. .

+3

, , , , Boost Signals2

, - Signal/Slot.

+1

​​: , , EvtHandler:

class Event; //implement this yourself, it shall contain general but good info about event

class EvtHandler
{
public:
    virtual void handleEvent (Event & evt);
};

, , , , , ( ) ( ). :

class Foo : public EvtHandler
{
public:
    void handleFooEvent (Event & event);
};

, :

class ShutdownMessageCenter
{
typedef std::map<EventHandler *, event_func> ListenerMap; 
public:

    void register (EvtHandler * handler, void(EvtHandler::*memFunc)(Event &)) {
        m_lmap[handler] = memFunc;
    }

     void callListeners () {
         Event shutdown_event (EM_SHUTDOWN /*just imagine this can mean something, idk*/);
         ListenerMap::iterator itr = m_lmap.begin ();
         for (; itr != m_lmap.end(); ++itr) {
            EvtHandler * handler = itr->first;
            void (EvtHandler::*func)(Event &) = itr->second;
            (handler->*func)(shutdown_event);
          }
      }

private:
   ListenerMap m_lmap;
};

EvtHandlers , !

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 ();

, , ! , -!

+1

, ( ++/cli .net).

, , , , - . ( ).

0

, - - . () , , -.

class myClass{
public:
  static void callback(void *arg, void *obj)
  {
    if (obj)
      reinterpret_cast<myClass*>(obj)->cb(arg);
  }

private:
  void cb(void *arg);
};

myClass::callback this . , , arg, , .

0

All Articles