观察者模式通过Subject维护Observer列表实现一对多依赖,当状态变化时自动通知所有观察者;代码中ConcreteSubject用vector存储Observer指针,调用notify遍历执行update,输出显示注册的观察者接收消息,移除后不再通知。
在C++中实现观察者模式(Observer Pattern),核心是定义一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。当主题状态发生变化时,所有注册的观察者都会自动收到通知并更新。
Subject(被观察者):维护观察者列表,提供注册、注销和通知接口。
Observer(观察者):定义接收通知的接口,通常是一个纯虚函数。
当主题状态改变时,调用通知方法,遍历所有观察者并调用其更新函数。
下面是一个简洁但完整的C++实现:
#include#include #include // 观察者接口 class Observer { public: virtual ~Observer() = default; virtual void update(const std::string& message) = 0; };
// 被观察者接口 class Subject { public: virtual ~Subject() = default; virtual void attach(Observer obs) = 0; virtual void detach(Observer obs) = 0; virtual void notify(const std::string& message) = 0; };
// 具体被观察者 class ConcreteSubject : public Subject { private: std::vector
observers; std::string state; public: void setState(const std::string& s) { state = s; notify(state); }
std::string getState() const { return state; } void attach(Observer* obs) override { observers.push_back(obs); } void detach(Observer* obs) override { observers.erase( std::remove(observers.begin(), observers.end(), obs), observers.end() ); } void notify(const std::string& message) override { for (Observer* obs : observers) { obs-youjiankuohaophpcnupdate(message); } }
};
// 具体观察者 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 zuojiankuohaophpcnzuojiankuohaophpcn name zuojiankuohaophpcnzuojiankuohaophpcn " 收到通知: " zuojiankuohaophpcnzuojiankuohaophpcn message zuojiankuohaophpcnzuojiankuohaophpcn "\n"; }};
使用示例
演示如何注册观察者并触发通知:
int main() { ConcreteSubject subject;ConcreteObserver observer1("观察者A"); ConcreteObserver observer2("观察者B"); subject.attach(&observer1); subject.attach(&observer2); subject.setState("系统状态已更新!"); subject.detach(&observer2); subject.setState("第二次更新,只有A会收到"); return 0;}
输出结果:
观察者A 收到通知: 系统状态已更新!
观察者B 收到通知: 系统状态已更新!
观察者A 收到通知: 第二次更新,只有A会收到关键细节说明
使用裸指针时需确保观察者生命周期长于被观察者,否则可能引发悬空指针。若需更安全的管理,可改用智能指针(如std::weak_ptr)结合信号槽机制,或使用std::shared_ptr配合enable_shared_from_this。
基本上就这些。这种实现方式简单直观,适合理解模式本质,也可根据项目需求扩展支持异步通知、事件过滤等功能。
# go # ai # c++ # ios # stream # red # String # const # 指针 # 虚函数 # 纯虚函数 # 接口 # class # public # private # 空指针 # 对象 # 事件 # 异步 # 是一个 # 遍历 # 多个 # 也可 # 等功能 # 移除 # 时需 # 若需 # iostream # false
相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334 】
相关推荐: php怎么连接数据库_MySQL数据库连接的基础代码编写【说明】 如何从 Go 的 map[string]interface{} 中安全获取值 Win11怎么关闭搜索历史 Win11清除搜索框最近记录【隐私】 How to Properly Use NumPy in VS Code c++ reinterpret_cast怎么用 c++最危险的类型转换【详解】 Win11文件扩展名怎么显示 Win11查看文件后缀名设置【步骤】 Win11怎么关闭开机声音_Win11系统启动提示音静音【教程】 Windows10电脑怎么设置防火墙出站规则_Win10禁止程序联网教程 c++如何使用std::bitset进行位图算法_c++ 快速查找与大规模数据排重【方法】 LINUX如何开放防火墙端口_Linux firewalld与iptables开放端口命令【安全配置】 Windows10蓝屏代码DPC_WATCHDOG_VIOLATION_Win10死机修复指南 Python与MongoDB NoSQL开发实战_文档模型与索引优化 LINUX怎么查看进程_LINUX ps命令查看运行服务 Windows10系统更新错误0x80070002_Win10自动更新失败手动修复 Win10怎么关闭自动更新错误重启 Win10策略禁止失败补丁强制重启【防护】 ACF 教程:正确更新嵌套在多层 Group 字段内的子字段 Mac怎么查看活动监视器_理解Mac进程和资源占用【指南】 Win10如何卸载Skype_Win10卸载Skype步骤【步骤】 windows系统如何安装cab更新补丁_windows手动安装更新包教程 Win11如何设置开机自动联网 Win11宽带连接自动拨号【步骤】 php错误怎么开启_display_errors与log_errors的设置【汇总】 Windows10系统怎么查看CPU核心数_Win10逻辑处理器数量查看 php接口返回数据乱码怎么办_php接口调试编码问题解决【指南】 Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递 Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤 如何在Golang中使用container/heap实现堆_Golang container/heap最小堆方法 Win11怎么设置系统还原_Windows11系统属性保护设置 c++中的CRTP是什么 c++奇异递归模板模式【进阶】 Win11怎么关闭透明效果_Windows11个性化颜色关闭透明 Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】 如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本 如何在Golang中操作嵌套切片指针_Golang多维slice修改 Win11如何更新显卡驱动 Win11检查和安装设备驱动程序【方法】 Python对象比较与排序_魔术方法解析【教程】 Win10怎么创建桌面快捷方式 Win10为应用创建快捷方式【步骤】 英国搜索:多数英国人认为语言搜索是未来搜索 如何在 Go 中可靠地测试含 time.Time 字段的结构体 如何在Golang中使用内置函数_Golanglen append make等使用技巧 如何诊断并终止卡死的 multiprocessing 子进程 Windows7如何安装系统镜像_Windows7系统安装教程【步骤】 Win10怎么设置开机密码_Windows10账户登录密码设置与取消 如何在Golang中使用encoding/gob序列化对象_存储和传输数据 Python邮件系统自动化教程_批量发送解析与模板应用 Win10怎样卸载TeamViewer_Win10卸载TeamViewer步骤【教程】 Win11怎么关闭任务栏小组件_Windows11隐藏任务栏天气图标 Linux如何使用Curl发送请求_Linux下API接口测试与文件下载技巧【步骤】 如何在 Go 中调用动态链接库(.so)中的函数 Win11局域网共享怎么设置 Win11文件夹网络共享教程【详解】 c++如何利用doxygen生成开发文档_c++ 代码注释规范与HTML文档导出【案例】 如何在Golang中理解指针比较_Golang地址比较与相等判断2025-11-02
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。