首先定义事件类型与回调函数,使用std::function和枚举标识事件;接着通过std::queue实现事件队列,存储待处理事件;然后建立事件映射表std::unordered_map<EventType, std::function<void()>>管理回调;在主循环中持续检查队列,非空则取出事件并执行对应回调;提供on()注册、emit()触发和run()启动循环的方法;最终实现解耦、响应式的单线程事件驱动模型,适用于GUI、网络等异步场景。

在C++中实现一个简单的事件循环,核心是建立一个能够持续监听和处理事件的机制。这类模型广泛应用于GUI框架、网络服务、游戏引擎等需要异步响应的场景。不需要依赖复杂的库,也可以通过基础语言特性构建出清晰可用的事件驱动结构。
定义事件与回调函数
事件可以是用户输入、定时器触发、数据到达等。为统一处理,先定义事件类型和对应的响应行为。
使用函数对象(std::function)来表示回调,搭配枚举或字符串标识事件类型:
- 定义事件类型,如 enum class EventType { Click, Timer, KeyPress };
- 用 std::map 或哈希表存储事件到回调函数的映射;
- 回调函数签名统一为 std::function<void()>,便于注册和调用。
构建事件队列与分发机制
事件可能由外部产生并随时触发,需要用队列暂存,再由主循环依次处理。
立即学习“C++免费学习笔记(深入)”;
std::queue 配合事件结构体即可实现基本队列:
- 结构体包含事件类型和附加数据(如时间戳、参数);
- 生产者(如IO线程、定时器)将事件 push 进队列;
- 事件循环从队列中 pop 事件,根据类型查找并执行注册的回调。
编写主事件循环
事件循环是一个持续运行的循环体,检查是否有新事件,并调度处理。
基本结构如下:
- 循环中调用非阻塞方式检查事件队列是否为空;
- 若不为空,取出事件并执行对应回调;
- 可加入 sleep_for 微小延迟,避免CPU空转;
- 提供退出条件(如收到 Quit 事件)以终止循环。
示例:简化版实现思路
实际代码中,可以用一个 EventLoop 类封装逻辑:
- 维护一个 std::unordered_map<EventType, std::function<void()>> handlers;
- 提供 on(EventType, callback) 方法注册监听;
- 提供 emit(EventType) 将事件加入队列;
- run() 方法启动循环,不断处理 pending 事件。
这种模型虽然简单,但已具备事件驱动的核心特征:解耦、响应式、可扩展。后续可加入异步任务、优先级队列、跨线程通信等增强功能。
基本上就这些,不复杂但容易忽略细节,比如线程安全和事件丢失问题。如果只是本地模块内使用,单线程循环足够清晰可靠。











