在C 中编写一个非常简单的事件类

Writing a very simple event class in C++

本文关键字:非常 一个 简单 事件      更新时间:2023-10-16

我正在尝试在C 中编写一个非常简单的事件或消息类。我希望该事件保留发生的时间和某些针对事件类型的数据。我目前拥有的是以下


class EventData{
public:
    virtual ~EventData(void) = 0;
};
struct Event{
    Event(EventType type, Time time, EventData *data = nullptr):
        type_(type), time_(time), data_(data)
    {}
    ~Event(void){
        if(data_) delete data_;
    }
    //Disable copying, event memory will be managed by EventManager
    Event(const Event& other) = delete;
    const EventType  type_;
    const Time       time_;
    const EventData *data_;
};

在我的主循环中,我有这样的东西,


bool running = true;
while(running){
    const Event* nextEvent = evtManager.getNextEvent();
    switch(nextEvent.type_){
    case EVT_A:
        const EventAData* data = static_cast<EventAData*>(nextEvent.data_);
        //do stuff
        break;
    }
    ...
    case EVT_END:
        running = false;
        break;
    }
}

那么问题是,是否有一种更有效的方法来执行此操作,即使用模板。另一个问题是某人可能会意外地给出错误的EventTypeEventData对,在这种情况下,static_cast将失败。

我应该注意,我希望此Event类尽可能快,尤其是对time_成员变量的访问。

  1. 无需在删除指针之前检查指针是否为null。
  2. 您正在尝试执行类型播放,然后根据刚刚删除的类型执行不同的任务。效率低下。相反,查看boost ::变体,看来这正是您所需要的。
  3. 如果您坚持使用此方法,则应使用typeid区分类型。

而不是使用模板,您可以使用继承。

事件可以是一个抽象基类,其中一个成员变量,_time。访问_time成员变量将使用简单的访问方法(可能是内在的)或使_Time成为公共成员变量的快速。您几乎总是使用访问者方法更好。访问将足够快,登录器将使您可以灵活地在需要时更改时间的内部表示。

您示例中的EventType枚举确实描述了事件的所有可能子类。如果您为EventType中的每个条目创建一个抽象基类事件的混凝土子类,那么您确实不需要EventType Enum。子类标识事件类型。所有子类的构造函数可能是唯一的,每个构建体都采用不同的参数。每个子类都可以为其成员变量提供访问者。这些附加的构造函数参数和登录器可以替换EventData类。

最后,您有两个替代方案的主循环。首先,您可能会在每个案例语句中处理当前进行的处理。事件基类可以具有称为" ProcessEvent()"的纯虚拟函数,每个子类都可以覆盖。如果可能的话,您可以用简单函数调用替换开关语句:

nextEvent->processEvent();

第二,如果这是不可行的,则可以使用RTTI从事件指针到适当子类的指针来降低NextEvent变量。然后,您可以调用特定于亚类的登记器执行类似于您当前正在做的处理的处理。