当前位置: 首页 > news >正文

C++观察者与事件系统

C++观察者与事件系统

观察者模式定义一对多依赖,当一个对象状态变化时,所有依赖对象自动收到通知。这是事件驱动系统的核心模式。

基本观察者模式包含主题和观察者接口。

#include
#include
#include
#include
#include
#include

class Observer {
public:
virtual ~Observer() = default;
virtual void on_notify(const std::string& event, const std::string& data) = 0;
virtual int id() const = 0;
};

class Subject {
std::vector> observers_;
public:
void attach(std::shared_ptr obs) {
observers_.push_back(obs);
std::cout << "Observer " << obs->id() << " attached\n";
}

void detach(std::shared_ptr obs) {
auto it = std::find_if(observers_.begin(), observers_.end(),
[&obs](const auto& o) { return o->id() == obs->id(); });
if (it != observers_.end()) {
observers_.erase(it);
}
}

void notify(const std::string& event, const std::string& data) {
for (auto& obs : observers_) {
obs->on_notify(event, data);
}
}
};

class ConcreteObserver : public Observer {
int id_;
std::string name_;
public:
ConcreteObserver(int id, const std::string& name) : id_(id), name_(name) {}

void on_notify(const std::string& event, const std::string& data) override {
std::cout << "Observer " << name_ << " (ID:" << id_ << "): "
<< "Event='" << event << "', Data='" << data << "'\n";
}

int id() const override { return id_; }
};

void observer_demo() {
Subject subject;

auto obs1 = std::make_shared(1, "Logger");
auto obs2 = std::make_shared(2, "Display");

subject.attach(obs1);
subject.attach(obs2);

subject.notify("data_changed", "Hello World");
subject.detach(obs2);
subject.notify("update", "After detach");
}

带事件过滤的观察者系统。

enum class EventType {
ALL = 0,
DATA_CHANGE,
ERROR,
STATUS
};

class FilteredObserver : public Observer {
int id_;
std::string name_;
std::vector subscribed_events_;
public:
FilteredObserver(int id, const std::string& name, std::vector events)
: id_(id), name_(name), subscribed_events_(events) {}

void on_notify(const std::string& event, const std::string& data) override {
std::cout << "Filtered " << name_ << ": " << event << " - " << data << "\n";
}

int id() const override { return id_; }

bool is_interested(EventType type) const {
if (subscribed_events_.empty()) return true;
return std::find(subscribed_events_.begin(), subscribed_events_.end(), type)
!= subscribed_events_.end();
}
};

基于回调的事件系统。

class EventEmitter {
std::vector> listeners_;
public:
void add_listener(std::function listener) {
listeners_.push_back(std::move(listener));
}

void emit(const std::string& event, int value) {
for (auto& listener : listeners_) {
listener(event, value);
}
}
};

void callback_event_demo() {
EventEmitter emitter;

emitter.add_listener([](const std::string& evt, int val) {
std::cout << "Listener 1: " << evt << " = " << val << "\n";
});

int total = 0;
emitter.add_listener([&total](const std::string& evt, int val) {
total += val;
std::cout << "Listener 2: total = " << total << "\n";
});

emitter.emit("click", 10);
emitter.emit("scroll", 20);
}

可断开的连接。

class Connection {
std::function disconnect_fn_;
public:
Connection() = default;
explicit Connection(std::function fn) : disconnect_fn_(std::move(fn)) {}

void disconnect() {
if (disconnect_fn_) {
disconnect_fn_();
disconnect_fn_ = nullptr;
}
}

Connection(Connection&& other) noexcept
: disconnect_fn_(std::move(other.disconnect_fn_)) {}
};

class DisconnectableEmitter {
std::map> slots_;
int next_id_ = 0;
public:
Connection connect(std::function slot) {
int id = next_id_++;
slots_[id] = std::move(slot);
return Connection([this, id]() { slots_.erase(id); });
}

void emit(int value) {
for (auto& [id, slot] : slots_) {
slot(value);
}
}
};

void disconnectable_demo() {
DisconnectableEmitter emitter;

auto conn1 = emitter.connect([](int v) {
std::cout << "Slot 1: " << v << "\n";
});

auto conn2 = emitter.connect([](int v) {
std::cout << "Slot 2: " << v * 2 << "\n";
});

emitter.emit(10);
conn1.disconnect();
emitter.emit(20);
}

观察者模式是MVC架构和事件驱动系统的基础。

http://www.jsqmd.com/news/1046359/

相关文章:

  • 2026菏泽漏水检测维修精选优质服务商TOP5推荐!卫生间漏水/厨房漏水/屋顶天花板漏水/阳台漏水/地下室漏水防水补漏检测维修-正规防水补漏公司优选口碑榜测评推荐 - 即刻修防水
  • 厂家工业专用吸尘器十大品牌排行榜2025:史沃斯稳居第一,挑战者厉邦紧随其后 - 工业清洁测评社
  • 2026年靠谱的重庆亲子农家乐/白市驿亲子采摘体验农家乐/重庆亲子研学基地/重庆周末亲子游优选推荐 - 行业平台推荐
  • 面试不慌!Java高级特性面试题全解析(附答案)
  • ComfyUI-KJNodes:基于虚拟连接与模块化设计的工作流编排引擎
  • zram 压缩内存 swap 配置实战:低内存服务器性能提升指南
  • 2026年热门的义乌拼箱代理/义乌货运代理哪家专业 - 品牌宣传支持者
  • eVTOL开发中的集成仿真系统:从模型设计到虚拟验证的工程实践
  • 从FWHM到σ:高斯波形解析中的关键几何关系与物理意义
  • C++栈与堆内存对比
  • 2026年比较好的阻燃编织网管/PPS编织网管厂家推荐与选型指南 - 行业平台推荐
  • 自监督学习在单细胞图像到组学预测中的应用与突破
  • LPC1768开发套件深度解析:从Drag2Flash到ARM Cortex-M3实战应用
  • 2026年知名的环保帆布袋/龙港帆布袋定制公司选择指南 - 品牌宣传支持者
  • 2026年口碑好的白市驿亲子烧烤游玩/重庆亲子户外休闲/重庆亲子研学基地/重庆农耕体验亲子农家乐哪家值得去 - 行业平台推荐
  • 2026年可靠的诸城硬膜拉伸热成型包装机/诸城真空拉伸膜包装机厂家精选合集 - 行业平台推荐
  • 2026永康全屋定制口碑爆棚的真相
  • 深入解析MCU定时器与PWM:从原理到实战,掌握MC68HC08AB16A TIMB模块
  • YOLO越界行为识别数据集:聚焦周界防护的实战型安防训练资源
  • 2026年可靠的液压防爆预警套管/光伏逆变器自卷套管/双层异色自卷纺织套管/尼龙自卷套管高口碑品牌推荐 - 行业平台推荐
  • 【2027最新】基于SpringBoot+Vue的web新能源充电系统管理系统源码+MyBatis+MySQL
  • WarcraftHelper完整指南:让经典魔兽争霸3焕发新生的终极免费工具
  • 球面多项式与矩匹配:高维统计与社会选择理论
  • 2026菏泽本地人必选防水补漏检测维修公司靠谱服务商TOP5推荐:房屋渗漏水检测维修/卫生间/厨房/天花板/阳台/外墙渗漏水检测补漏维修-暗管漏水检测专业仪器精准定位漏水点 - 即刻修防水
  • 嵌入式C语言信号处理:从数学库优化到实时滤波与特征提取实践
  • Appium手势自动化进阶:W3C Actions API原理与实战详解
  • 2026年知名的华亚CPVC管/华亚pph管/华亚管材公司介绍 - 品牌宣传支持者
  • FPGA实现GigE Vision相机图像采集与千兆UDP转换方案设计
  • 2026黄石2026正规漏水检测维修公司精选口碑榜TOP5权威推荐-精准定位检测漏水点-专业防水补漏堵漏维修、卫生间/厨房/屋顶/天沟/地下室/阳台防水漏水检测维修 - 安佳防水
  • 2026年优秀的pvc管/安徽pvc管/安徽pvc化工管/pvc排水管横向对比厂家推荐 - 行业平台推荐