当前位置: 首页> 汽车> 报价 > it程序员需要什么学历_创业计划书模板_seo培训师_北京seo排名服务

it程序员需要什么学历_创业计划书模板_seo培训师_北京seo排名服务

时间:2025/7/9 12:59:53来源:https://blog.csdn.net/2303_80346267/article/details/147062548 浏览次数: 0次
it程序员需要什么学历_创业计划书模板_seo培训师_北京seo排名服务

在现代软件架构中,事件通信(Event Communication) 已成为实现模块解耦与灵活扩展的关键机制。无论是 GUI 编程、游戏开发、插件系统,还是通用消息分发场景,我们都常常需要一种“非侵入式”的方式,在对象或模块之间传递消息。

由于 C++ 并不像 C#、JavaScript 等语言自带成熟的事件系统,我们通常需要自行设计或引入相应机制。本文聚焦两种经典模式:

  • 信号槽(Signal-Slot)

  • 事件总线(EventBus/DataBus)

我们将依次介绍它们的设计理念与适用场景,随后给出精简高效的实现代码,并配以示例,帮助你在实际项目中快速落地使用。


常见事件通信范式对比

模式同步/异步典型用途特征关键词
Callback / Listener✅ 同步库回调、小型模块简单、强绑定、函数指针
Signal-Slot✅ 同步UI 框架、组件事件一对多、模板信号、自动连接
EventBus / DataBus✅ 同步插件系统、模块通信类型驱动、广播机制、全局轻量
Observer Pattern✅ 同步MVC、状态同步被动通知、对象绑定、依附主体
Pub/Sub (消息队列)✅ 异步服务通信、日志系统异步、主题订阅、消息中间件
Command Pattern✅ 同步撤销重做、命令封装行为抽象、可组合
Event Queue / Reactor✅ 异步UI 循环、异步 I/O事件队列、非阻塞调度
Actor Model✅ 异步并发系统、微服务并发隔离、消息驱动

信号槽(Signal-Slot)实现

下面是一个轻量级、线程安全的信号槽实现,支持任意函数签名,可动态连接与断开。

#pragma once
#include <functional>
#include <vector>
#include <mutex>template <typename... Args>
class Signal {
private:std::mutex _mtx;std::vector<std::function<void(Args...)>> _slots;public:// 连接槽函数template <typename Slot>void connect(Slot&& fn) {std::lock_guard<std::mutex> lock(_mtx);_slots.emplace_back(std::forward<Slot>(fn));}// 发射信号,调用所有槽void emit(Args... args) {std::vector<std::function<void(Args...)>> copy;{std::lock_guard<std::mutex> lock(_mtx);copy = _slots;}for (const auto& slot : copy) {slot(args...);}}// 断开所有槽函数void disconnectAll() {std::lock_guard<std::mutex> lock(_mtx);_slots.clear();}// 获取当前连接数量size_t count() const {std::lock_guard<std::mutex> lock(_mtx);return _slots.size();}
};

事件总线(EventBus)实现

以下是一个典型的类型驱动事件总线实现,支持任意事件类型,全局静态管理,线程安全。

#pragma once
#include <functional>
#include <vector>
#include <mutex>
#include <type_traits>class EventBus {
private:template<typename T>static std::mutex& _mutex() {static std::mutex mtx;return mtx;}template<typename T>static std::vector<std::function<void(const T&)>>& _slots() {static std::vector<std::function<void(const T&)>> slots;return slots;}public:// 订阅事件类型 Ttemplate <typename T>static void on(std::function<void(const T&)> fn) {using Type = std::decay_t<T>;std::lock_guard<std::mutex> lock(_mutex<Type>());_slots<Type>().emplace_back(std::move(fn));}// 发布事件template <typename T>static void emit(T&& e) {using Type = std::decay_t<T>;std::vector<std::function<void(const Type&)>> copy;{std::lock_guard<std::mutex> lock(_mutex<Type>());copy = _slots<Type>();}for (const auto& fn : copy) {fn(e);}}// 清除所有该类型的事件监听template <typename T>static void clear() {using Type = std::decay_t<T>;std::lock_guard<std::mutex> lock(_mutex<Type>());_slots<Type>().clear();}
};

使用示例

信号槽示例

**信号槽(Signal-Slot)**是一种观察者范式的变体,强调“一发多收”的调用链。发送方通过 emit() 发射信号,所有已连接的槽函数将被同步调用,常用于 UI 响应、模块内部通信等场景。

#include <iostream>
#include "Signal.hpp"void globalHandler(int value) {std::cout << "全局槽函数:value = " << value << std::endl;
}int main() {Signal<int> signal;signal.connect(globalHandler);  // 连接全局函数signal.connect([](int v) {std::cout << "Lambda 槽函数:v = " << v * 2 << std::endl;});signal.emit(42);  // 发射信号std::cout << "当前连接数: " << signal.count() << std::endl;signal.disconnectAll();return 0;
}

输出:

全局槽函数:value = 42
Lambda 槽函数:v = 84
当前连接数: 2

事件总线示例

**事件总线(EventBus)**则采用“发布-订阅”的设计理念,基于类型进行事件分发。任何模块都可以发布某类事件,所有对此事件类型感兴趣的订阅者将被自动调用,无需双方直接依赖,极适用于插件系统、游戏逻辑等全局通信场景。

#include <iostream>
#include <string>
#include "EventBus.hpp"struct UserCreatedEvent {std::string username;
};struct LogEvent {std::string message;
};int main() {EventBus::on<UserCreatedEvent>([](const UserCreatedEvent& e) {std::cout << "用户创建事件:用户名 = " << e.username << std::endl;});EventBus::on<LogEvent>([](const LogEvent& e) {std::cout << "日志事件:消息 = " << e.message << std::endl;});EventBus::emit(UserCreatedEvent{"alice"});EventBus::emit(LogEvent{"用户已创建"});return 0;
}

输出:

用户创建事件:用户名 = alice
日志事件:消息 = 用户已创建

信号槽 vs 事件总线:对比总结

特性信号槽(Signal)事件总线(EventBus)
通信范式观察者模式(响应式)发布-订阅(类型驱动)
接收方注册方式明确调用 connect()全局注册 on<T>()
发射方式emit(args...)emit(Event{})
解耦程度模块级解耦全局解耦
线程安全✅ 是✅ 是
推荐场景UI、组件通信插件、后端模块、游戏逻辑

结语

信号槽与事件总线作为 C++ 中两种高效的事件通信范式,各自具备清晰的设计哲学与适用边界:

  • 若你希望对象间直接响应绑定,选择 信号槽(Signal) 更加直观;

  • 若你更倾向于模块间彻底解耦的通信机制,推荐使用 事件总线(EventBus)

本文提供的两种轻量实现,可在你的项目中直接使用或作为扩展基础。如需支持更高级功能(如:异步处理、优先级队列、自动解绑等),可在此架构之上进一步演化构建更完整的事件系统。

关键字:it程序员需要什么学历_创业计划书模板_seo培训师_北京seo排名服务

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: