新闻中心

C++怎么实现观察者模式_C++设计模式与观察者模式实现

2025-11-09
浏览次数:
返回列表
观察者模式通过定义一对多依赖关系实现对象间解耦,当主题状态改变时自动通知所有观察者;C++中可通过抽象基类结合虚函数实现多态更新,或使用std::function注册回调提升灵活性,需注意避免通知时修改列表、防止悬挂指针及多线程同步问题,适用于事件系统与数据绑定等场景。

c++怎么实现观察者模式_c++设计模式与观察者模式实现

观察者模式是一种行为设计模式,用于在对象之间定义一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。在C++中,我们可以通过抽象基类、指针或引用管理观察者列表来实现这一模式。

观察者模式的核心角色

在实现前,先明确两个关键角色:

  • Subject(主题):被观察的对象,维护一个观察者列表,提供添加、删除和通知观察者的方法。
  • Observer(观察者):定义一个更新接口,所有具体观察者都要实现它,以便接收通知。

使用抽象基类实现观察者模式

这是最常见且类型安全的实现方式。通过虚函数实现多态,让不同观察者响应同一通知。

// Observer.h

#ifndef OBSERVER_H
#define OBSERVER_H

class Subject;

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

#endif

易标AI 易标AI

告别低效手工,迎接AI标书新时代!3分钟智能生成,行业唯一具备查重功能,自动避雷废标项

易标AI 135 查看详情 易标AI

// Subject.h

#ifndef SUBJECT_H
#define SUBJECT_H

#include
#include gorithm>

class Observer;

class Subject {
private:
    std::vector observers;
protected:
    void notify() {
        for (auto observer : observers) {
            observer->update(this);
        }
    }
public:
    virtual ~Subject() = default;
    void attach(Observer* o) {
        observers.push_back(o);
    }
    void detach(Observer* o) {
        observers.erase(
            std::remove(observers.begin(), observers.end(), o),
            observers.end());
    }
};

#endif

// 具体主题示例:温度传感器

#include "Subject.h"
#include iostream>

class TemperatureSensor : public Subject {
private:
    double temperature;
public:
    double getTemperature() const { return temperature; }
    void setTemperature(double temp) {
        temperature = temp;
        notify(); // 状态变化,通知所有观察者
    }
};

// 具体观察者示例

#include "Observer.h"
#include "Subject.h"
#include stream>

class Display : public Observer {
public:
    void update(Subject* subject) override {
        if (auto* sensor = dynamic_cast(subject)) {
            std::cout getTemperature()         }
    }
};

使用函数对象或lambda增强灵活性

如果不需要严格的类继承结构,可以用函数指针或std::function来注册回调,使代码更简洁。

#include
#include

class EventPublisher {
private:
    std::vector<:function>> listeners;
public:
    void subscribe(std::function func) {
        listeners.push_back(func);
    }
    void notify() {
        for (const auto& f : listeners) {
            f();
        }
    }
};

// 使用示例:
EventPublisher pub;
pub.subscribe([]() { std::cout pub.notify();

注意事项与最佳实践

在实际使用中需要注意以下几点:

  • 避免在通知过程中修改观察者列表,可能导致迭代器失效。
  • 建议在析构主题或观察者时主动调用detach,防止悬挂指针。
  • 可结合智能指针(如shared_ptr/weak_ptr)管理生命周期,但Subject持有Observer的裸指针通常更合适,避免循环引用。
  • 多线程环境下需加锁保护观察者列表。

基本上就这些。观察者模式能有效解耦对象间的通信,适合实现事件系统、GUI组件更新、数据绑定等场景。C++中通过虚函数或多态函数对象都能灵活实现,关键是根据项目需求选择合适的抽象层级。

以上就是C++怎么实现观察者模式_C++设计模式与观察者模式实现的详细内容,更多请关注其它相关文章!


# 管理机制  # seo文章中放外链  # 郑州网站优化推广服务  # 天津网站建设集团地址  # 湖北网站推广引流  # 山东专业seo软件  # 麻涌外贸公司网站推广  # 莱芜网站建设排行  # 佛山建材网站seo优化  # 株洲网站seo优化价格  # 床商品的SEO词  # 复用  # 多路  # go  # 如何实现  # 何为  # 回调  # 绑定  # 都是  # 多态  # 多线程  # red  # stream  # ios  # c++ 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 谷歌google账号怎么注册账号 谷歌账号注册官方流程  Composer如何在生产环境安全地执行composer update  大麦的“候补”是什么意思 大麦候补购票规则【详解】  Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑  CSS图片焦点样式实现教程:理解与应用tabindex属性  如何在更新Composer依赖后自动运行测试_使用post-update-cmd钩子触发PHPUnit  必由学官网快捷入口 必由学网页版在线学习平台  手机屏幕碎了但能正常使用怎么办 手机外屏碎裂的修复建议  快速CSGO开箱网站指南 CSGO开箱平台推荐  sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤  迅雷下载到U盘速度很慢怎么办_迅雷U盘下载慢优化方法  拷贝漫画电脑版官网入口 拷贝漫画(PC版)在线直达  自定义Bag-of-Words实现:处理带负号的词汇权重  c++如何实现单例设计模式_c++线程安全的单例模式写法  b站怎么看视频的弹幕数量_b站弹幕数量查看方法  AO3访问入口汇总 AO3网页版同人作品一键直达  抖音未来赚钱的新趋势 2025年值得关注的变现风口分析  绝地鸭卫平a核爆刀流玩法攻略  Golang如何使用context实现超时取消_Golang context超时取消模式实践  AO3最新镜像入口 Archive of Our Own官方平台访问  2025-2030年全球乘用车销量预测:新能源成增长主力  机构:以往存储涨价周期小米利润率实际上有所改善 能转嫁给消费者等  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析  Pyrogram与g4f集成:异步编程实践与常见错误解决  一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法  Spyder启动失败:字体文件权限拒绝错误解决方案  单12V-2&#215;6实现为RTX 5090供电750W!甚至都没敢跑分  CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题  抓大鹅解压小游戏 抓大鹅摸鱼解压入口  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  漫蛙网页登录入口 漫蛙漫画官方授权网址  Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践  php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】  Typer应用中动态命令行参数的解析与处理  J*aScript DOM操作:高效清空列表元素的策略与实践  TikTok评论显示延迟如何处理 TikTok评论刷新优化方法  PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】  必由学在线入口 必由学网页版快速登录入口  sublime怎么进行远程开发编辑_配置rsub/rmate实现sublime编辑服务器文件  Win11怎么隐藏桌面图标 Win11一键隐藏所有桌面元素及恢复显示  PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航  Django模型中自动计算可用余额的实现方法  Safari浏览器输入栏卡顿如何解决 Safari搜索建议与缓存清理  PrimeNG Sidebar背景色自定义指南:CSS覆盖与主题化实践  word中如何让数字纵向排列_Word数字纵向排列方法  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  在Qt QML中通过Python字典动态更新TextEdit内容的教程 

搜索