c++实现消息发布/订阅机制例子(成员函数被其他类掉调用)
简单的消息发布订阅机制
以下是一个简单的使用 C++ 实现发布 / 订阅机制的示例代码。这个示例包含一个简单的事件系统,其中有发布者(Publisher
)和订阅者(Subscriber
)。
以下代码需要C++11以上支持
这个同时也是:成员函数被其他类掉调用的例子
#include <iostream> #include <vector> #include <functional> // 事件参数结构体,可以根据实际需求修改 struct EventData { int value; }; // 事件处理函数类型定义 using EventHandler = std::function<void(const EventData&)>; // 发布者类 class Publisher { public: void publish(const EventData& data) { for (const auto& handler : subscribers) { handler(data); } } void subscribe(EventHandler handler) { subscribers.push_back(handler); } private: std::vector<EventHandler> subscribers; }; // 订阅者类示例 class Subscriber { public: Subscriber(const std::string& name) : name(name) {} void onEvent(const EventData& data) { std::cout << name << " received event with value: " << data.value << std::endl; } private: std::string name; }; int main() { Publisher publisher; Subscriber sub1("Subscriber 1"); Subscriber sub2("Subscriber 2"); // 订阅者注册事件处理函数,这里将sub1的onEvent成员函数,传入到publisher的容器中,被后续publish触发调用。 publisher.subscribe(std::bind(&Subscriber::onEvent, sub1, std::placeholders::_1)); publisher.subscribe(std::bind(&Subscriber::onEvent, sub2, std::placeholders::_1)); EventData event = { 42 }; publisher.publish(event); EventData event2 = { 43 }; publisher.publish(event2); return 0; }
注意,这是一个非常基础的发布 / 订阅机制示例,在实际应用中,可能需要更多的功能,如事件类型的区分、动态订阅 / 取消订阅、多线程安全性等。
注意,这里的 Publisher 其实应改成 EventBus ,更能体现消息管理与订阅的解耦。
============================================升级扩展===================================================
添加事件过滤功能
注意:这里为了将原来的消息订阅机制与观察者模式做强烈的区分,将Publisher类改成EventBus类(消息管理总线)
以下代码需要C++17以上支持
#include <iostream> #include <vector> #include <functional> #include<map> #include<unordered_map> // 事件参数结构体,可以根据实际需求修改 struct EventData { int value; //具体的消息,可扩展 std::string type; //消息类型,目前用字符串表示 }; // 事件处理函数类型定义 using EventHandler = std::function<void(const EventData&)>; //// 事件总线类,独立的公共消息通道 class EventBus { private: // 使用vector存储事件处理函数及其过滤器 std::vector<std::pair<EventHandler, std::vector<std::string>>> handlersAndFilters; public: int subscribe(EventHandler handler, const std::vector<std::string>& filter = {}) { handlersAndFilters.push_back({ handler, filter }); return handlersAndFilters.size() - 1; } void publish(const EventData& data) { for (size_t i = 0; i < handlersAndFilters.size(); ++i) { //基于C++17 的结构化绑定,给handler和filter使用handlersAndFilters[i]里面的pair进行赋值操作 const auto& [handler, filter] = handlersAndFilters[i]; if (filter.empty()) { handler(data); } else { for (const auto& type : filter) { if (type == data.type) { handler(data); break; } } } } } }; // 订阅者类示例 class Subscriber { public: Subscriber(const std::string& name) : name(name) {} void onEvent(const EventData& data) { std::cout << name << " received event with value: " << data.value << " and type: " << data.type << std::endl; } private: std::string name; }; int main() { EventBus eventBus; Subscriber sub1("Subscriber 1"); Subscriber sub2("Subscriber 2"); // 订阅者1只订阅类型为"type1"(消息类型)的事件 eventBus.subscribe(std::bind(&Subscriber::onEvent, sub1, std::placeholders::_1), { "type1" }); // 订阅者2订阅所有事件(没有设置过滤器) eventBus.subscribe(std::bind(&Subscriber::onEvent, sub2, std::placeholders::_1)); EventData event1 = { 42, "type1" };//消息类型为"type1"的事件,消息内容为42 EventData event2 = { 30, "type2" };//消息类型为"type2"的事件,消息内容为30 eventBus.publish(event1);//这里的消息可以被"Subscriber 1"和"Subscriber 2"同时捕获订阅消息,消息内容 42 eventBus.publish(event2);//这里的消息可以被"Subscriber 2"捕获订阅消息,而"Subscriber 1"只能订阅"type1"类型的消息,消息内容 30 return 0; }
输出结果:
Subscriber 1 received event with value : 42 and type : type1 Subscriber 2 received event with value : 42 and type : type1 Subscriber 2 received event with value : 30 and type : type2