新闻中心
c++如何实现观察者设计模式_c++行为型设计模式实战
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题状态改变时自动通知所有观察者进行更新;其核心角色包括Subject(维护观察者列表并负责注册、移除和通知)和Observer(定义更新接口),通过C++示例展示了具体实现结构,包含ConcreteSubject和ConcreteObserver类,并演示了消息广播与解注册行为;实际应用中建议结合智能指针避免内存问题,使用std::function提升灵活性,注意线程安全与生命周期管理,适用于GUI事件、消息总线等解耦场景。

观察者模式是一种常用的行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,会通知所有观察者,使它们自动更新。
核心角色说明
在观察者模式中有两个主要角色:
- Subject(被观察者):维护观察者列表,提供注册、移除和通知接口。
- Observer(观察者):定义接收更新通知的接口,具体观察者实现该接口。
基础实现结构
下面是一个使用C++实现观察者模式的简单示例:
#include <iostream>
#include <vector>
#include <algorithm>
<p>// 观察者接口
class Observer {
public:
virtual ~Observer() = default;
virtual void update(const std::string& message) = 0;
};</p><p>// 被观察者接口
class Subject {
public:
virtual ~Subject() = default;
virtual void attach(Observer<em> observer) = 0;
virtual void detach(Observer</em> observer) = 0;
virtual void notify() = 0;
virtual void setMessage(const std::string& message) = 0;
virtual std::string getMessage() const = 0;
};</p><p>// 具体被观察者
class ConcreteSubject : public Subject {
private:
std::vector<Observer*> observers;
std::string message;</p><p>public:
void attach(Observer* observer) override {
observers.push_back(observer);
}</p><pre class='brush:php;toolbar:false;'>void detach(Observer* observer) override {
obse
rvers.erase(
std::remove(observers.begin(), observers.end(), observer),
observers.end()
);
}
void notify() override {
for (auto* obs : observers) {
obs->update(message);
}
}
void setMessage(const std::string& msg) override {
message = msg;
notify();
}
std::string getMessage() const override {
return message;
}};
N世界
一分钟搭建会展元宇宙
138
查看详情
// 具体观察者 class ConcreteObserver : public Observer { private: std::string name;
public: ConcreteObserver(const std::string& n) : name(n) {}
void update(const std::string& message) override {
std::cout << "Observer " << name
<< " received update: " << message << "\n";
}};
使用示例
测试代码展示如何注册观察者并触发通知:
int main() {
ConcreteSubject subject;
<pre class='brush:php;toolbar:false;'>ConcreteObserver observer1("A");
ConcreteObserver observer2("B");
subject.attach(&observer1);
subject.attach(&observer2);
subject.setMessage("Hello Observers!");
// 输出:
// Observer A received update: Hello Observers!
// Observer B received update: Hello Observers!
subject.detach(&observer2);
subject.setMessage("Only A should see this.");
// 只有 A 收到消息
return 0;}
实际应用场景建议
在真实项目中,可以结合智能指针和回调机制增强安全性与灵活性:
- 使用
std::shared_ptr<observer></observer>避免悬空指针问题。 - 通过
std::function<void std::string></void>实现函数式观察者,简化回调逻辑。 - 在线程安全场景下,对观察者列表的操作应加锁保护。
基本上就这些。观察者模式适合解耦事件源与响应逻辑,广泛用于GUI事件系统、消息总线或状态同步等场景。关键是管理好生命周期,避免野指针或重复通知。不复杂但容易忽略细节。
以上就是c++++如何实现观察者设计模式_c++行为型设计模式实战的详细内容,更多请关注其它相关文章!
# 管理机制
# 宝安网站建设定制
# 最新推广视频素材网站
# 集群网站优化
# 剪映营销推广视频模板怎么做
# 正规的网站优化效果如何
# seo免费优化软件
# 福保网站的网站建设
# 三明seo变现
# 彭州成交型网站建设
# 滁州网站优化有哪些
# 复用
# 多路
# go
# 实际应用
# 移除
# 何为
# 回调
# 多个
# 都是
# 如何实现
# red
# stream
# ios
# c++
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比
韩剧圈正版入口页面_韩剧圈官网登录链接
漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现
在Pyomo中实现基于变量的条件约束:Big-M方法详解
精准捕获:如何在页面中监听除特定元素外的所有点击事件
J*a最大堆Heapify方法修复:索引计算与边界条件深度解析
AI泡沫首次被“刺破”:GPU十年都无法存活!
火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧
MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具
j*a toString()的覆盖
qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决
微信网页版扫码登录入口 微信网页版二维码登录入口
126邮箱手机版登录官网2026_126手机邮箱免费入口最新
php源码怎么看淘宝客系统_看php源码淘宝客系统技巧
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
Yandex免登录网页版地址 Yandex搜索引擎官方访问入口
html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】
必由学官方网站入口 必由学学生教师共用登录通道
python3时间如何用calendar输出?
Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】
126邮箱账号注册 电脑版登录入口
Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略
抖音网页版快捷访问 抖音网页版网页版入口操作教程
uc手机浏览器网页版入口 uc浏览器手机版便捷登录首页
如何在CSS中使用浮动制作导航栏_float实现水平菜单
J*aScript类型检查_j*ascript代码规范
c++ 获取系统当前时间 c++时间戳获取方法
网易大神怎么保存别人动态的图片_网易大神动态图片保存方法
蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版
Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法
sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤
UC浏览器网页版登录入口官网 电脑版网址入口
荣耀Play7T运行卡顿解决_荣耀Play7T性能优化
React中useState与局部变量:理解组件状态管理与渲染机制
mc.js官网登录入口 mc.js官方登录入口最新版
PHP中高效并行检查多链接状态的教程
如何在Python中使用Optional类型处理可变对象并避免Pylint警告
俄罗斯Yandex搜索引擎入口_Yandex官网免登录一键访问
J*a里如何使用forEach遍历Map_Map遍历方法说明
QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录
192.168.1.1管理中心入口 192.168.1.1路由器网页设置平台
Go语言中对Map值调用带指针接收者方法:原理与最佳实践
“在文档元素之后找到了标记”是什么错误? 检查并修复XML中多个根元素的3个方法
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】
如何使用spryker/configurable-bundles-products-resource-relationship模块解决复杂产品捆绑关系难题
c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换
PyTorch模型训练效果不佳?深入剖析常见错误与调试技巧


2025-11-29
浏览次数:次
返回列表
rvers.erase(
std::remove(observers.begin(), observers.end(), observer),
observers.end()
);
}
void notify() override {
for (auto* obs : observers) {
obs->update(message);
}
}
void setMessage(const std::string& msg) override {
message = msg;
notify();
}
std::string getMessage() const override {
return message;
}