全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C++如何实现观察者设计模式?C++代码解耦实战【设计模式】

观察者模式在C++中通过抽象基类解耦Subject与Observer,用std::vector+weak_ptr管理观察者并自动清理,模板化SubjectBase提升复用性,具体类仅需继承并调用notify(),新增观察者零侵入。

观察者模式在C++中核心是解耦“被观察者”(Subject)和“观察者”(Observer),让两者只依赖抽象,不依赖具体实现。关键在于用抽象类定义接口、用容器管理观察者、用虚函数触发通知——不用信号槽、不依赖第三方库,纯标准C++就能落地。

定义抽象观察者和被观察者接口

先写两个纯虚基类:Observer 声明 update() 接口,Subject 声明 attach()/detach()/notify() 接口。所有具体类都继承它们,这样新增观察者或被观察者时,原有代码完全不用改。

注意:Observer 的 update() 通常接收 const Subject& 或 shared_ptr,避免拷贝、防止误修改;Subject 内部用 std::vector<:weak_ptr>> 存观察者,避免循环引用导致内存泄漏。

实现可复用的 Subject 基类模板

把通用逻辑抽成模板,减少重复代码。例如:

// 模板化 Subject 基类,自动管理 weak_ptr 观察者
template
class SubjectBase {
protected:
  std::vector<:weak_ptr>> observers_;
public:
  void attach(std::shared_ptr obs) {
    observers_.push_back(obs);
  }
  void notify() const {
    for (auto it = observers_.begin(); it != observers_.end();) {
      if (auto obs = it->lock()) {
        obs->update(*this);
        ++it;
      } else {
        it = observers_.erase(it); // 自动清理已销毁的观察者
      }
    }
  }
};

具体业务类按需继承并触发通知

比如一个温度传感器类:

class TemperatureSensor : public SubjectBase {
private:
  double temperature_ = 0.0;
public:
  void setTemperature(double t) {
    temperature_ = t;
    notify(); // 数据一变就广播,不关心谁在监听
  }
  double getTemperature() const { return temperature_; }
};

再写具体观察者,比如控制台打印器和日志记录器,都只实现自己的 update(),互不影响:

  • ConsoleDisplay::update() —— printf 当前温度
  • Logger::update() —— 写入文件或发网络请求

使用时只需组合,不修改已有类

main() 里创建对象、建立关系即可:

int main() {
  auto sensor = std::make_shared();
  auto display = std::make_shared();
  auto logger = std::make_shared();

  sensor->attach(display);
  sensor->attach(logger);

  sensor->setTemperature(25.6); // 自动触发 display 和 logger
  sensor->setTemperature(26.1); // 同样自动通知
}

以后加新功能(比如发邮件告警),只要写个 EmailAlert 类继承 Observer,实现 update(),再 attach 进去——零侵入、无编译依赖、职责清晰。

基本上就这些。不复杂但容易忽略 weak_ptr 清理、const 正确性、以及模板接口的泛化粒度。写熟了,一个项目里几十个松耦合的通知场景,都能靠这几行基类搞定。


# ai  # c++  # oled  # red  # if  # for  # printf  # const  # auto  # int  # double  # void  # 循环  # 继承  # 虚函数  # 接口  # 类模板  # class  # public  # private  # protected  # 对象  # this  # display  # 传感器  # 自己的  # 复用  # 不依赖  # 记录器  # 就能  # 都能  # 已有  # 只需  # 第三方  # 谁在 


相关文章: 如何在Golang中指定模块版本_使用go.mod控制版本号  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  如何快速查询域名建站关键信息?  网站制作话术技巧,网站推广做的好怎么话术?  常州企业网站制作公司,全国继续教育网怎么登录?  高防服务器租用首荐平台,企业级优惠套餐快速部署  平台云上自助建站如何快速打造专业网站?  如何高效利用200m空间完成建站?  如何做静态网页,sublimetext3.0制作静态网页?  完全自定义免费建站平台:主题模板在线生成一站式服务  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  企业微网站怎么做,公司网站和公众号有什么区别?  建站之星图片链接生成指南:自助建站与智能设计教程  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  深圳网站制作培训,深圳哪些招聘网站比较好?  利用JavaScript实现拖拽改变元素大小  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  如何撰写建站申请书?关键要点有哪些?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  如何通过多用户协作模板快速搭建高效企业网站?  jQuery 常见小例汇总  如何通过FTP服务器快速搭建网站?  定制建站哪家更专业可靠?推荐榜单揭晓  无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?  建站之星官网登录失败?如何快速解决?  如何选择高效稳定的ISP建站解决方案?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  官网自助建站平台指南:在线制作、快速建站与模板选择全解析  宝塔建站教程:一键部署配置流程与SEO优化实战指南  网页设计网站制作软件,microsoft office哪个可以创建网页?  宝塔Windows建站如何避免显示默认IIS页面?  如何通过老薛主机一键快速建站?  如何确保西部建站助手FTP传输的安全性?  C#如何使用XPathNavigator高效查询XML  建站之星代理如何优化在线客服效率?  网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?  浅析上传头像示例及其注意事项  C++用Dijkstra(迪杰斯特拉)算法求最短路径  ,网站推广常用方法?  小程序网站制作需要准备什么资料,如何制作小程序?  如何快速搭建支持数据库操作的智能建站平台?  图册素材网站设计制作软件,图册的导出方式有几种?  广州营销型建站服务商推荐:技术优势与SEO优化解析  整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?  北京网站制作的公司有哪些,北京白云观官方网站?  建站之星备案流程有哪些注意事项?  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  岳西云建站教程与模板下载_一站式快速建站系统操作指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。