设计模式之观察者模式(优先使用对象组合的原则)的C++实现

观察者模式又称订阅者发布者模式,本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式,这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类,减少了一层类的继承;当然,具体情况需要可根据需求进行订阅者发布者模式的代码设计。

代码实现如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>using Callback = std::function<void(int)>;
class Subcribe{
public:Subcribe(Callback func):m_callback(std::move(func)){};void RecievData(int val){printf("Recive data val = %d \n",val);m_callback(val);}private:Callback m_callback;
};//单例基类
template<class T>
class SingleIns{
public:static T& GetInstance(){static T a;return a;}
protected:SingleIns()=default;
};class Publisher:public SingleIns<Publisher>{
public:void Attach(Subcribe* obj){if(std::count(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj) > 0){printf("Attach the subscriber already exist\n");return;}m_vecSubscribers.push_back(obj);};void Detach(Subcribe* obj){auto it = std::find(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj);if(it != m_vecSubscribers.end()){m_vecSubscribers.erase(it);}}void UpdateVal(int val){if(m_vecSubscribers.size() == 0){printf("The m_vecSubscribers is empty\n");return;}if(m_val != val){m_val = val;Notify();}else{printf("The updated data is equal\n");}}private:void Notify(){for(auto it = m_vecSubscribers.begin();it !=m_vecSubscribers.end();it++){(*it)->RecievData(m_val);}};std::vector<Subcribe*>m_vecSubscribers;int m_val;};class User1{
public:void GetData(int val){printf("User1 Get data = %d\n",val);};void Init(){Publisher::GetInstance().Attach(&m_subscirbe);}Subcribe& GetSubObj(){return m_subscirbe;};  //对象组合
private:Subcribe m_subscirbe{std::bind(&User1::GetData,this,std::placeholders::_1)};
};class User2{
public:void GetData(int val){printf("User1 Get data *2 = %d\n",val*2);};void Init(){Publisher::GetInstance().Attach(&m_subscirbe);}Subcribe& GetSubObj(){return m_subscirbe;}; //对象组合
private:Subcribe m_subscirbe{std::bind(&User2::GetData,this,std::placeholders::_1)};
};int main()
{User1 obj;obj.Init();Publisher::GetInstance().UpdateVal(1);Publisher::GetInstance().UpdateVal(2);Publisher::GetInstance().UpdateVal(3);Publisher::GetInstance().UpdateVal(3);Publisher::GetInstance().Detach(&obj.GetSubObj());Publisher::GetInstance().UpdateVal(6);printf("\n**************************\n\n");User2 obj2;obj2.Init();Publisher::GetInstance().UpdateVal(5);Publisher::GetInstance().UpdateVal(6);Publisher::GetInstance().Detach(&obj2.GetSubObj());Publisher::GetInstance().UpdateVal(7);return 0;
}

程序运行结果如下:

7377db541f0d401594075079cd515498.png

附加知识:单例模式C++实现和观察者模式C++实现_实现观察者模式,并画出其类图 c++-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/826769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive 中常用的函数以及数据类型

数据类型 1.基本数据类型: 数据类型大小范围示例TINYINT1byte-128 ~ 127100YSMALLINT2byte-32768 ~ 32767100SINT4byte-2^32~ 2^32-1100BIGINT8byte-2^64~ 2^64-1100LFLOAT4byte单精度浮点数5.21DOUBLE8byte双精度浮点数5.21DECIMAL-高精度浮点数DECIMAL(9,8)BOOLEAN-布尔型tr…

linux 下的 sqlite数据库

SQLite 认识 SQLite简介 轻量化&#xff0c;易用的嵌入式数据库&#xff0c;用于设备端的数据管理&#xff0c;可以理解成单点的数据库。传统服务器型数据库用于管理多端设备&#xff0c;更加复杂 SQLite是一个无服务器的数据库&#xff0c;是自包含的。这也称为嵌入式数据库&…

【语音识别】在Win11使用Docker部署FunASR服务器

文章目录 在 Win11 使用 Docker 部署 FunASR 服务器镜像启动服务端启动监控服务端日志下载测试案例使用测试案例打开基于 HTML 的案例连接ASR服务端 关闭FunASR服务 在 Win11 使用 Docker 部署 FunASR 服务器 该文章因官网文档不详细故写的经验论 官网文章&#xff1a;https:/…

Docker - WEB应用实例

原文地址&#xff0c;使用效果更佳&#xff01; Docker - WEB应用实例 | CoderMast编程桅杆Docker - WEB应用实例 在之前的章节中&#xff0c;仅对普通容器进行了演示&#xff0c;但在实际中常常使用到 Docker 容器中的 WEB 应用程序。 运行一个WEB应用 拉取镜像 创建一个容器…

NewStarCTF 2023 web

目录 week1 泄漏的秘密 Begin of Upload Begin of HTTP ErrorFlask Begin of PHP R!C!E! EasyLogin week2 游戏高手 include 0。0 ez_sql Unserialize&#xff1f; Upload again! R!!C!!E!! week3 Include &#x1f350; medium_sql POP Gadget GenShin wee…

unity学习(89)——unity塞满c盘!--删除editor下的log文件

卸了一个视频后强制续命打开详细信息&#xff1a; 这个再往下找也是没用的&#xff01; 显示隐藏文件夹后&#xff01;执行如下操作&#xff01; 30个g&#xff01; 其中unity占23g editer占了21g 删除C:\Users\王栋林\AppData\Local\Unity\Editor下的log文件 恢复到之前的水…

【编译原理】03语法分析

1&#xff0c;语法分析的若干问题 1.1 语法分析器的作用 编译器前端的重要组成部分&#xff1a; (1) 根据词法分析器提供的记号流&#xff0c;为语法正确的输入构造分析树(或语法树)。 (2) 检查输入中的语法(可能包括词法)错误&#xff0c;并调用出错处理器进…

JMeter--逻辑控制器--IF 控制器

IF控制器&#xff1a;可以控制其下面的子/后代元素是否执行&#xff1b;如果为 true 则执行&#xff1b;如果为 false 则都不执行 右键 >>> 添加 >>> 逻辑控制器 >>> IF 控制器&#xff08;If Controller&#xff09; Interpret Condition as Varia…

031——从GUI->Client->Server->driver实现dht11数据的采集

目录 0、设置ip 1、修改显示界面 2、 修改客户端 3、 修改服务器程序通信部分 4、 修改驱动处理程序 5、 重写驱动程序 6、 展示 0、设置ip 因为ifconfig命令要被淘汰了&#xff0c;所以我们改成使用ip命令设置ubuntu的ip ip addr add 192.168.5.10/24 dev ens36 ip …

ElasticSearch中使用向量和关键词联合检索

注&#xff1a;案例测试数据及其索引构建详见&#xff1a;ElasticSearch中使用bge-large-zh-v1.5进行向量检索&#xff08;一&#xff09;-CSDN博客 中的第三部分。 假设任务场景为&#xff1a;用“新疆”向量检索相关的数据&#xff0c;同时需要匹配关键词“巴州”。 首先获取…

VUE运行找不到pinia模块

当我们的VUE运行时报错Module not found: Error: Cant resolve pinia in时 当我们出现这个错误时 可能是 没有pinia模块 此时我们之要下载一下这个模块就可以了 npm install pinia

负载均衡的原理和算法

负载均衡——这是一个在网络世界中非常重要的概念。 一&#xff0c; 负载均衡的原理 想象一下&#xff0c;你在学校的食堂里&#xff0c;只有一个厨师在忙碌地为所有饥饿的学生准备午餐。如果每个人都排队等同一个厨师&#xff0c;那么等待时间会很长&#xff0c;而且厨师可能…

axios的两种请求方法

第一种写法 axios.get("http://geek.itheima.net/v1_0/channels").then((response) > {console.log(response.data.data.channels);setDataList(response.data.data.channels);console.log("dataList", dataList);}).catch((error) > {console.err(…

html-docx-js网页转为word格式框架

第一步&#xff1a;安装html-docx-js依赖 npm install html-docx-js --save-dev 第二步&#xff1a;引入网页转为word格式方法 import htmlToDocx from html-docx-js/dist/html-docx; 第三步&#xff1a;使用网页转为word格式方法 const content this.$refs.content.inne…

Elasticsearch进阶篇(三):ik分词器的使用与项目应用

ik分词器的使用 一、下载并安装1.1 已有作者编译后的包文件1.2 只有源代码的版本1.3 安装ik分词插件 二、ik分词器的模式2.1 ik_smart演示2.2 ik_max_word演示2.3 standard演示 三、ik分词器在项目中的使用四、ik配置文件4.1 配置文件的说明4.2 自定义词库 五、参考链接 一、下…

SPARK:性能调优之RSS

参考文章&#xff1a; 京东Spark自研Remote Shuffle Service在大促中的应用实践SPARK RSS 杂谈RSS设计文档 一、原生的 shuffle 过程 1、在mapper将shuffle数据写到本地磁盘&#xff0c;每个mapper会按照下游reducer的个数生成block 2、reducer在fetch环节拉取对应的block …

利用Opencv4.9为图像添加边框

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇利用OpenCV4.9制作自己的线性滤波器&#xff01; 下一篇 :OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 …

[Spring Cloud] (4)搭建Vue2与网关、微服务通信并配置跨域

文章目录 前言gatway网关跨域配置取消微服务跨域配置 创建vue2项目准备一个原始vue2项目安装vue-router创建路由vue.config.js配置修改App.vue修改 添加接口访问安装axios创建request.js创建index.js创建InfoApi.js main.jssecurityUtils.js 前端登录界面登录消息提示框 最终效…

故障诊断 | 用于跨机器工况下故障诊断的深度判别迁移学习网络附Pytorch代码

目录 基础代码小结基础 目前,研究者已经提出了很多用于解决目标域和源域之间的分布对齐和知识迁移问题的领域自适应方法。然而,大多数研究方法只关注到边缘分布对齐,忽略了目标域和源域之间判别性特征的学习。因此,在某些案例中,这些方法仍然不能很好地满足故障诊断要求。…

【iOS安全】iOS ARM汇编

mov指令 MOV X22, X0 将X0的值移到X22中 参数传递 参数1&#xff1a;寄存器X0传递 参数2&#xff1a;寄存器X1传递 参数3&#xff1a;寄存器X2传递 参数4&#xff1a;寄存器X3传递 &#xff08;这里的X0传递的就是第一个实际参数&#xff0c;而不是self、selector之类的&…