Calling C++ class methods via a function pointer

前端 未结 10 979
醉酒成梦
醉酒成梦 2020-11-22 06:47

How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:

class Dog : A         


        
10条回答
  •  感动是毒
    2020-11-22 07:17

    I did this with std::function and std::bind..

    I wrote this EventManager class that stores a vector of handlers in an unordered_map that maps event types (which are just const unsigned int, I have a big namespace-scoped enum of them) to a vector of handlers for that event type.

    In my EventManagerTests class, I set up an event handler, like this:

    auto delegate = std::bind(&EventManagerTests::OnKeyDown, this, std::placeholders::_1);
    event_manager.AddEventListener(kEventKeyDown, delegate);
    

    Here's the AddEventListener function:

    std::vector::iterator EventManager::AddEventListener(EventType _event_type, EventHandler _handler)
    {
        if (listeners_.count(_event_type) == 0) 
        {
            listeners_.emplace(_event_type, new std::vector());
        }
        std::vector::iterator it = listeners_[_event_type]->end();
        listeners_[_event_type]->push_back(_handler);       
        return it;
    }
    

    Here's the EventHandler type definition:

    typedef std::function EventHandler;
    

    Then back in EventManagerTests::RaiseEvent, I do this:

    Engine::KeyDownEvent event(39);
    event_manager.RaiseEvent(1, (Engine::Event*) & event);
    

    Here's the code for EventManager::RaiseEvent:

    void EventManager::RaiseEvent(EventType _event_type, Event * _event)
    {
        if (listeners_.count(_event_type) > 0)
        {
            std::vector * vec = listeners_[_event_type];
            std::for_each(
                begin(*vec), 
                end(*vec), 
                [_event](EventHandler handler) mutable 
                {
                    (handler)(_event);
                }
            );
        }
    }
    

    This works. I get the call in EventManagerTests::OnKeyDown. I have to delete the vectors come clean up time, but once I do that there are no leaks. Raising an event takes about 5 microseconds on my computer, which is circa 2008. Not exactly super fast, but. Fair enough as long as I know that and I don't use it in ultra hot code.

    I'd like to speed it up by rolling my own std::function and std::bind, and maybe using an array of arrays rather than an unordered_map of vectors, but I haven't quite figured out how to store a member function pointer and call it from code that knows nothing about the class being called. Eyelash's answer looks Very Interesting..

提交回复
热议问题