C++如何实现观察者模式_C++实现松耦合的发布-订阅设计模式


观察者模式通过主题-观察者机制实现一对多依赖,状态变更时自动通知所有观察者。主题类维护观察者列表并提供注册、注销和通知接口,使用抽象基类降低耦合;观察者接口定义更新方法,具体观察者在update中响应状态变化。C++通过虚函数和指针实现松耦合,适用于事件处理、GUI更新等场景,提升系统可扩展性与可维护性。

观察者模式是一种行为设计模式,适用于对象间一对多依赖关系的场景。当一个对象状态改变时,所有依赖它的对象都会自动收到通知。这种机制在事件处理系统、GUI界面更新、消息广播等场景中非常常见。C++中可以通过抽象类和指针管理实现松耦合的发布-订阅机制。

定义主题(Subject)接口

主题是被观察的对象,它维护一个观察者列表,并提供注册、注销和通知的接口。使用抽象基类可以降低耦合度,让具体主题灵活扩展。

  • 声明添加观察者(attach)、移除观察者(detach)和通知(notify)方法
  • 状态变更后调用 notify,避免观察者轮询
  • 用 std::vector 或 std::list 存储观察者指针
class Observer; // 前向声明

class Subject {
public:
    virtual ~Subject() = default;
    virtual void attach(Observer* obs);
    virtual void detach(Observer* obs);
    virtual void notify();

    void setState(int state) {
        m_state = state;
        notify(); // 状态改变时主动通知
    }

    int getState() const { return m_state; }

protected:
    std::vector m_observers;

private:
    int m_state = 0;
};

定义观察者(Observer)接口

观察者需要定义一个更新接口,由主题在状态变化时调用。每个具体观察者自行决定如何响应通知。

  • update 是纯虚函数,子类必须实现
  • 可传入 subject 指针,便于获取最新状态
  • 避免在 update 中修改 subject,防止迭代器失效
class Subject; // 再次前向声明以解决循环依赖

class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(Subject* subject) = 0;
};

实现具体观察者

具体观察者继承 Observer 接口,在 update 中执行实际逻辑,比如打印信息或更新本地缓存。

class ConcreteObserver : public Observer {
public:
    explicit ConcreteObserver(std::string name) : m_name(std::move(name)) {}

    void update(Subject* subject) override {
        int state = subject->getState();
        std::cout << m_name << " received update, new state: " << state << "\n";
    }

private:
    std::string m_name;
};

完整示例与使用方式

将上述组件组合起来,演示发布-订阅流程:

#include 
#include 
#include 

// (前面的类定义放在这里)

void Subject::attach(Observer* obs) {
    m_observers.push_back(obs);
}

void Subject::detach(Observer* obs) {
    m_observers.erase(
        std::remove(m_observers.begin(), m_observers.end(), obs),
        m_observers.end()
    );
}

void Subject::notify() {
    for (auto* obs : m_observers) {
        obs->update(this);
    }
}

int main() {
    Subject subject;
    ConcreteObserver observerA("ObserverA");
    ConcreteObserver observerB("ObserverB");

    subject.attach(&observerA);
    subject.attach(&observerB);

    subject.setState(10); // 两者都会收到通知

    subject.detach(&observerA); // 取消订阅
    subject.setState(20);      // 只有 B 收到

    return 0;
}

输出结果:

ObserverA received update, new state: 10
ObserverB received update, new state: 10
ObserverB received update, new state: 20

基本上就这些。通过虚函数和指针引用,C++实现了松耦合的观察者模式。主题无需知道观察者的具体类型,只需调用统一接口。这种设计提升了系统的可扩展性和可维护性,适合构建模块化软件结构。


# ai  # c++  # ios  # stream  # 子类  # 指针  # 继承  # 虚函数  # 纯虚函数  # 接口  # 对象  # 事件  # 适用于  # 前向  # 是一种  # 放在  # 只需  # 可以通过  # 移除  # 实现了  # 迭代 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Win11任务栏天气怎么关闭 Win11隐藏天气小组件图标【设置】  c++怎么使用std::tuple存储多元组数据_c++ 11获取元素与解包操作【技巧】  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  Win11无法拖拽文件到任务栏怎么办_Win11开启拖放功能修复【方法】  Win11怎么关闭键盘按键音_Win11禁用打字声音反馈【教程】  如何使用Golang匿名函数_快速定义临时函数逻辑  Windows10无法连接到Internet_Win10网络重置命令详解  MySQL 中使用 IF 和 CASE 实现查询字段的条件转换  Win11怎么设置虚拟键盘_打开Win11屏幕键盘操作指南【技巧】  Python函数接口文档化_自动化说明【指导】  Win11怎么关闭自动维护 Win11禁用系统自动维护功能【优化】  Windows 10怎么隐藏特定更新补丁_Windows 10使用微软官方工具wushowhide.diagcab  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  如何在Golang中处理数据库事务错误_回滚和日志记录  c++中如何使用虚函数实现多态_c++多态性实现原理  Win11怎么忘记WiFi网络_Win11删除已保存无线连接【教程】  Win11如何关闭小娜Cortana Win11禁用Cortana语音助手【优化】  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  Win10路由器怎么隐藏ssid Win10隐藏wifi名称设置【指南】  C++如何使用std::transform批量处理容器元素?(代码示例)  Win10怎么卸载爱奇艺_Win10彻底卸载爱奇艺方法【步骤】  Mac上的iMovie如何剪辑视频?(新手入门教程)  Python包结构设计_大型项目组织解析【指导】  全球各国上班时间表外贸邮件时间  如何在Golang中处理二进制数据_Golang io与encoding/binary二进制操作方法  Win11怎么激活Windows10_Win11激活Win10系统方法【步骤】  如何在 Go 中高效缓存与分发网络视频流  Mac如何与安卓手机传文件_Mac和Android设备互通【必备工具】  Mac怎么进行语音输入_Mac听写功能设置与使用【教程】  如何解决Windows时间不准的问题?(自动同步设置)  php转exe用什么工具打包快_高效打包软件推荐【汇总】  如何在Golang中处理通道发送接收错误_防止阻塞或panic  如何在 Go 中创建包含映射(map)的切片(slice)结构  Win11怎么压缩文件 Win11自带压缩解压功能使用【教程】  PHP的FastAdmin架构适合二次开发吗_特点分析【介绍】  PHP主流架构怎么处理表单验证_规则与自定义【技巧】  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  Windows 11无法安全删除U盘提示设备正在使用中怎么办_Windows 11找出占用设备进程  如何使用Golang table-driven基准测试_多组数据测量函数效率  Win11怎样安装钉钉客户端_Win11安装钉钉教程【步骤】  Win11怎么关闭系统推荐内容_Windows11开始菜单布局设置  PHP接收参数值为空怎么办_判断和处理空参数方法说明【说明】  如何外贸网站设计-能留住客户提升用户体验!  Windows11如何设置专注助手_Windows11专注助手使用攻略【技巧】  Win11怎么设置屏保时间_调整Win11屏幕保护等待时间【详解】  Windows10系统更新错误0x80070002_Win10自动更新失败手动修复  c++20的std::format怎么用 比printf更安全高效的格式化方法【详解】  php8.4如何实现队列任务_php8.4redis队列简单实现方法【教程】  Mac如何调整Dock栏大小和位置_Mac程序坞个性化设置  Win11怎么设置按流量计费_Win11限制后台流量消耗【网络】 

 2025-12-24

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.