eventpp 全面教程(从入门到实战)
eventpp 全面教程(从入门到实战)eventpp 是一款轻量级、类型安全、无依赖的纯 C++11 及以上事件分发/回调管理库(事件总线),核心价值是简化 C++ 项目的模块解耦与回调管理,仅专注于“事件-回调”的绑定、分发与生命周期管理,不具备事件循环和 IO 处理能力。本教程将从基础入门、核心用法、高级特性到实战场景,全方位讲解 eventpp 的使用。一、教程前置准备1. 环境要求编译器:支持 C++11 及以上标准(GCC 4.8+、Clang 3.3+、MSVC 2013+)无外部依赖:无需安装第三方库,仅需头文件/源码集成跨平台:支持 Linux、macOS、Windows 等主流操作系统2. 源码集成eventpp 是头文件/源码级库,无需编译安装,集成步骤如下:下载源码:从 GitHub eventpp 仓库 下载最新源码项目集成:将源码中的eventpp/include/eventpp/目录复制到项目中,在代码中通过#include eventpp/xxx.h引入对应头文件编译配置:编译时指定 C++11 及以上标准(如 GCC 编译添加-std=c++11参数)二、核心概念(入门基础)在使用 eventpp 前,必须掌握 3 个核心概念,它们是理解 eventpp 设计的基础:概念含义与作用EventBus(事件总线)核心管理容器,负责存储“事件类型-回调函数”的映射关系,提供注册、注销、触发事件的接口,支持单例/多例使用Event(事件)触发回调的“信号标识”,可以是整数、枚举、字符串等任意可哈希类型(推荐枚举/强类型,保证类型安全)Callback(回调)事件触发时执行的业务逻辑,支持普通函数、Lambda 表达式、类成员函数、函数对象,支持带参/无参、有返回值/无返回值三、基础入门:核心API使用1. 头文件引入eventpp 核心功能通过eventbus.h提供,基础使用只需引入:#includeeventpp/eventbus.h2. 第一步:定义事件类型推荐使用枚举(enum/class)作为事件类型,保证类型安全,避免字符串/整数的硬编码错误:// 普通枚举(兼容旧版C++)enumBasicEvent{Event_Init,// 初始化事件Event_Quit// 退出事件};// 强类型枚举(推荐,避免枚举值冲突)enumclassBusinessEvent{UserRegister,// 用户注册事件OrderPay// 订单支付事件};// 字符串类型事件(灵活,适合动态事件场景)usingStringEvent=std::string;3. 第二步:创建事件总线事件总线是模板类,模板参数说明:第一个参数:事件类型(如枚举、字符串)第二个参数:回调函数签名(格式:返回值类型(参数类型1, 参数类型2, ...),无参无返回值为void ())// 示例1:无参无返回值的事件总线(对应 BasicEvent 枚举)eventpp::EventBusBasicEvent,void()basicEventBus;// 示例2:带参数的事件总线(对应 BusinessEvent 枚举,回调接收2个参数)eventpp::EventBusBusinessEvent,void(int,std::string)businessEventBus;// 示例3:字符串事件类型 + 带返回值的事件总线eventpp::EventBusStringEvent,int(std::string)stringEventBus;4. 第三步:注册事件与回调eventpp 提供appendListener接口注册回调,支持多种回调类型,核心用法如下:(1)注册普通函数回调// 普通函数(匹配 BasicEvent 事件总线的回调签名:void ())voidonEventInit(){std::cout"普通函数:初始化事件触发"std::endl;}voidonEventQuit(){std::cout"普通函数:退出事件触发"std::endl;}// 注册普通函数basicEventBus.appendListener(BasicEvent::Event_Init,onEventInit);basicEventBus.appendListener(BasicEvent::Event_Quit,onEventQuit);(2)注册 Lambda 表达式回调Lambda 表达式支持捕获外部变量,是最灵活的回调方式:// 无捕获 Lambda(匹配 BasicEvent 回调签名)basicEventBus.appendListener(BasicEvent::Event_Init,[](){std::cout"Lambda 无捕获:初始化事件触发"std::endl;});// 有捕获 Lambda(匹配 BusinessEvent 回调签名:void (int, std::string))std::string tip="业务通知:";businessEventBus.appendListener(BusinessEvent::UserRegister,[tip](intuserId,std::string userName){std::couttip"用户注册:ID="userId",用户名="userNamestd::endl;});(3)注册类成员函数回调类成员函数需要通过std::bind绑定类实例,才能注册到事件总线:classOrderService{public:// 类成员函数(匹配 BusinessEvent 回调签名)voidonOrderPay(intorderId,std::string orderNo){std::cout"【OrderService】订单支付:ID="orderId",订单号="orderNostd::endl;}};// 实例化类OrderService orderService;// 注册类成员函数(std::bind 绑定实例地址和函数地址)businessEventBus.appendListener(BusinessEvent::OrderPay,std::bind(OrderService::onOrderPay,orderService,std::placeholders::_1,std::placeholders::_2));(4)同一事件注册多个回调eventpp 支持给同一个事件注册多个回调,触发事件时会串行执行所有回调:// 给 Event_Init 注册3个回调basicEventBus.appendListener(BasicEvent::Event_Init,onEventInit);basicEventBus.appendListener(BasicEvent::Event_Init,[](){std::cout"Lambda 回调1"std::endl;});basicEventBus.appendListener(BasicEvent::Event_Init,[](){std::cout"Lambda 回调2"std::endl;});5. 第四步:触发(分发)事件通过dispatch接口触发事件,传递的参数需与回调签名严格匹配:// 示例1:触发无参事件std::cout"--- 触发初始化事件 ---"std::endl;basicEventBus.dispatch(BasicEvent::Event_Init);std::cout"\n--- 触发退出事件 ---"std::endl;basicEventBus.dispatch(BasicEvent::Event_Quit);// 示例2:触发带参数事件std::cout"\n--- 触发用户注册事件 ---"