新闻中心

c++如何实现观察者设计模式_c++行为型设计模式实战

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

c++如何实现观察者设计模式_c++行为型设计模式实战

观察者模式是一种常用的行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,会通知所有观察者,使它们自动更新。

核心角色说明

在观察者模式中有两个主要角色:

  • 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 {
    observers.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世界 N世界

一分钟搭建会展元宇宙

N世界 138 查看详情 N世界

// 具体观察者 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模型训练效果不佳?深入剖析常见错误与调试技巧 

搜索