本机C++11事件-没有任何绑定的事件引发错误

Native C++11 Event - Event with nothing bound throws error

本文关键字:事件 绑定 错误 C++11 本机 任何      更新时间:2023-10-16

我有一个这样的事件处理程序,

    __event void MouseMoved(int MousePosX, int MousePosY);

并通过提升

    __raise MouseMoved(MousePosX, MousePosY);

在使用__hook向事件添加函数后,这一操作非常好;然而,如果我引发,即使任何绑定到事件的函数都会出现运行时错误。在引发事件之前,是否有方法检查事件是否为空?

C++’11没有本机事件。C++’14也是如此。

在我看来,这是Microsoft Visual C++特有的功能——也许是Microsoft的统一事件模型?如果是这样的话,根据他们的文档,引发一个没有订阅者的事件不应该导致错误:

要激发事件,只需调用在事件源类中声明为事件的方法。如果处理程序已挂接到事件,则将调用处理程序。

另一方面,.NET要求您在引发事件之前检查事件是否为null,并且您正在使用的关键字也可以在托管C++项目中使用,因此如果您创建了一个托管应用程序,则很可能需要执行类似的操作

if(MouseMoved != nullptr) {
  __raise MouseMoved(MousePosX, MousePosY);
}

如果你想编写在其他编译器和/或平台上运行的可移植C++,我可以推荐libsigc++或JL Signal。

我选择只定义自己的事件对象,该对象包含可以按顺序调用的函数指针列表。If函数与C#中的事件和事件处理程序非常相似。

struct EventArg
{
public:
    EventArg(){}
    ~EventArg(){}
    static EventArg Empty()
    {
        EventArg empty;
        return empty;
    }
};

template <typename T>
class EventHandler
{
public:
    EventHandler(void(T::*functionHandle)(void*, EventArg), T* receiver)
    {
        this->functionHandle = functionHandle;
        this->receiver = receiver;
    }
    virtual void Call(void* sender, EventArg e)
    {
        (receiver->*functionHandle)(sender, e);
    }
private:
    void (T::*functionHandle)(void*, EventArg);
    T* receiver;
};
class Event
{
private:
    std::vector<EventHandlerBase*> EventHandlers;
public:
    void Raise(void* sender, EventArgT e)
    {
        for (auto item = EventHandlers.begin(); item != EventHandlers.end(); item++)
            (*item)->Call(sender, e);
    }
    void Add(EventHandler* functionHandle)
    {
        EventHandlers.push_back(functionHandle);
    }
    void Remove(EventHandler* functionHandle)
    {
        for (auto item = EventHandlers.begin(); item != EventHandlers.end(); item++)
        {
            if ((*item) == functionHandle)
            {
                EventHandlers.erase(item);
                return;
            }
        }
    }
}