C ++ 11 Observers在Notify上传递参数

时间:2015-04-03 00:12:27

标签: c++11 notify observers

我来自C#并尝试在c ++ 11中实现一个简单的Events / EventHandler模​​式,我相信通用名称是观察者和信号,我知道有升级库和其他但我不想使用任何外部库。

在网上搜索时,我发现了一个简单的实现,因此我接受并修改了代码,它运行正常。

我的问题是参数在注册事件/观察者时传递,而不是在提升/发信号/通知时我发现有点尴尬。

class EventManager
{
private:

static std::map<EventType, std::vector<std::function<void()>>> _eventHandlers;

public:
EventManager() = default;


template <typename EventHandler>
static void RegisterEventHandler(EventType&& eventType, EventHandler&& eventHandler)
{
    EventManager::_eventHandlers[std::move(eventType)].push_back(std::forward<EventHandler>(eventHandler));
}   

static void Raise(const EventType& event)
{
    for (const auto& eventHandler : EventManager::_eventHandlers.at(event))
    {

        eventHandler();
    }
}

// disallow copying and assigning
EventManager(const EventManager&) = delete;
EventManager& operator=(const EventManager&) = delete;


};

任何人都可以通过在举起活动时添加接受参数的功能来帮助我扩展以下代码吗?

2 个答案:

答案 0 :(得分:1)

我相信这解决了你的问题:

// g++ -std=c++11 -o /tmp/events /tmp/events.cpp && /tmp/events
// handler=1 arg=1
// handler=2 arg=1
// handler=1 arg=2
// handler=2 arg=2

#include <functional>
#include <map>
#include <vector>

template<class EventType, class... HandlerArgs>
class EventManager
{
public:
    using EventHandler = std::function< void(HandlerArgs...) >;

    void register_event(EventType&& event, EventHandler&& handler)
        {
            _handlers[std::move(event)].push_back(std::forward<EventHandler>(handler));
        }

    void raise_event(const EventType& event, HandlerArgs&&... args)
        {
            for (const auto& handler: EventManager::_handlers.at(event)) {
                handler(std::forward<HandlerArgs>(args)...);
            }
        }

private:
    std::map<EventType, std::vector<EventHandler>> _handlers;

};

int main(int argc, char **argv)
{
    EventManager<int, int> m;
    m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 1, arg); });
    m.register_event(1, [](int arg) { printf("handler=%d arg=%d\n", 2, arg); });
    m.raise_event(1, 1);
    m.raise_event(1, 2);
}

PS:我删除了所有关于非可复制性的代码,因为它与此问题无关。

答案 1 :(得分:0)

由于我没有得到任何答案,我想办法这样做,但我不喜欢它,因为我想要一个更好的方法,但很好地创建一个静态类,每个事件都有静态变量,在提升事件之前,调用者将设置这些变量,处理程序将读取然后重置它们。这是危险的方法,尤其是多线程,因为一个或多个线程可能会在通过mutli线程引发相同事件时更改值,因此我必须实现一些锁定功能以确保线程安全。

是的,我知道这不是最好的方法,但因为我不是C ++的专家,这个问题没有得到任何评论或答案,所以这是我接下来的方法。

相关问题