观察者模式-委托(大话设计模式)C/C++版本

观察者模式-委托

先看该常规的没有委托概念的代码,如下:

非委托

#include <iostream>
#include <string>
#include <list>
using namespace std;class Subject; // 前向声明// 抽象观察者
class Observer
{
protected:string name;Subject *sub;public:Observer(string name, Subject *sub){this->name = name;this->sub = sub;}virtual void update() = 0;
};// 抽象通知者
class Subject
{
protected:list<Observer *> observers;public:string event;virtual void attach(Observer *) = 0;virtual void detach(Observer *) = 0;virtual void notify() = 0;
};// 具体通知者,秘书
class Secretary : public Subject
{void attach(Observer *observer) override{observers.push_back(observer);}void detach(Observer *observer) override{list<Observer *>::iterator iter = observers.begin();while (iter != observers.end()){if ((*iter) == observer){observers.erase(iter);}++iter;}}void notify() override{list<Observer *>::iterator iter = observers.begin();while (iter != observers.end()){(*iter)->update();++iter;}}
};// 具体的观察者,看股票的
class StockObserver : public Observer
{
public:StockObserver(string name, Subject *sub) : Observer(name, sub){}void update() override{cout << name << " 收到消息:" << sub->event << endl;if (sub->event == "梁所长来了!"){cout << "我马上关闭股票,装做很认真工作的样子!" << endl;}}
};// 具体的观察者,看NBA的
class NBAObserver : public Observer
{
public:NBAObserver(string name, Subject *sub) : Observer(name, sub){}void update() override{cout << name << " 收到消息:" << sub->event << endl;if (sub->event == "梁所长来了!"){cout << "我马上关闭NBA,装做很认真工作的样子!" << endl;}}
};int main()
{// 创建通知者Subject *dwq = new Secretary();// 被观察的对象Observer *xs = new NBAObserver("xiaoshuai", dwq);Observer *lm = new StockObserver("limin", dwq);// 加入观察队列dwq->attach(xs);dwq->attach(lm);// 事件dwq->event = "去吃饭了!";// 通知dwq->notify();cout << endl;// 事件dwq->event = "梁所长来了!";// 通知dwq->notify();cout << endl;return 0;
}

观察者为什么要和委托有联系?

  1. 抽象通知类还是依赖抽象观察者类
  2. 不同的被观察者可能并不相关,所以设计的接口不一定全都是一样的接口名称update.
    总结这两点,就是去除抽象观察者这个基类后,并且该更新状态的接口不同名的情况下,观察者模式仍旧可以成立。

何谓委托(大概了解即可)

委托是一种设计原则,指的是一个对象(委托者)将自身的一部分职责或功能交由另一个对象(被委托者)来执行。这种机制允许对象专注于自己的核心功能,同时利用外部对象的专业能力来完成辅助任务。委托强调的是行为的传递和执行,而不是对象所有权或生命周期的管理
在这里插入图片描述

那么,C++如何实现委托?

function+bind
参考:https://blog.csdn.net/qq_38410730/article/details/103637778
https://www.cnblogs.com/linuxAndMcu/p/14576162.html#_label1

# include <functional>
std::function<函数类型>

std::function是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。

# include <functional>
std::bind(函数指针, 绑定对象);

std::bind可以看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应原对象的参数列表

这样就可以实现:直接将具体观察者实例和观察者类状态更新接口函数(即之前的update)绑定。通知类管理的通知对象就从观察者实例变成了观察者的函数对象了。

也就是达到了:通知类不再依赖抽象观察者类的update接口,而是直接依赖这个绑定的函数对象。这样就可以达到:不需要抽象观察者类并且可以使用不同的接口名。

委托

参考:https://blog.csdn.net/weixin_43272766/article/details/94166777

  1. 去除了抽象观察者类
  2. 使用了C++的function+bind实现委托
#include <iostream>
#include <string>
#include <functional>
#include <list>
using namespace std;// 
typedef function<void()> Action;// 抽象观察者 无// 抽象通知者
class Subject
{
protected:list<Action *> actions;public:string event;virtual void attach(Action *a) = 0;virtual void detach(Action *a) = 0;virtual void notify() = 0;
};// 具体通知者,秘书
class Secretary : public Subject
{
public:void attach(Action *a) override{actions.push_back(a);}void detach(Action *a) override{actions.remove(a);}void notify() override{for (auto act : actions){(*act)();}}
};// 具体的观察者,看股票的
class StockObserver
{
private:string name;Subject *sub;public:StockObserver(string _name, Subject *_sub) : name(_name), sub(_sub){}void StockObserverUpdate(){cout << name << " 收到消息:" << sub->event << endl;if (sub->event == "梁所长来了!"){cout << "我马上关闭股票,装做很认真工作的样子!" << endl;}}
};// 具体的观察者,看NBA的
class NBAObserver
{
private:string name;Subject *sub;public:NBAObserver(string _name, Subject *_sub) : name(_name), sub(_sub){}void NBAObserverUpdate(){cout << name << " 收到消息:" << sub->event << endl;if (sub->event == "梁所长来了!"){cout << "我马上关闭股票,装做很认真工作的样子!" << endl;}}
};int main()
{// 创建通知者Subject *dwq = new Secretary();// 被观察的对象NBAObserver *xs = new NBAObserver("xiaoshuai", dwq);Action acA = bind(&NBAObserver::NBAObserverUpdate, xs);StockObserver *lm = new StockObserver("limin", dwq);Action acB = bind(&StockObserver::StockObserverUpdate, lm);// 加入观察者队列dwq->attach(&acA);dwq->attach(&acB);// 事件dwq->event = "去吃饭了!";// 通知dwq->notify();cout << endl;// 事件dwq->event = "梁所长来了!";// 通知dwq->notify();cout << endl;return 0;
}

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

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

相关文章

二手物品交易系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商家管理&#xff0c;用户管理&#xff0c;商品管理&#xff0c;用户咨询管理 商家账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品管理&#xff0c;用…

荣耀笔记本IP地址查看方法详解:轻松掌握网络配置技巧

在数字化时代的浪潮中&#xff0c;笔记本电脑已经成为我们生活和工作中不可或缺的重要工具。对于荣耀笔记本用户而言&#xff0c;掌握基本的网络配置技巧显得尤为重要。其中&#xff0c;查看IP地址是连接网络、配置设备、排除故障等场景下的关键步骤。本文将详细介绍荣耀笔记本…

数据采集项目2-业务数据同步

全量同步 每天都将业务数据库中的全部数据同步一份到数据仓库 全量同步采用DataX datax datax使用 执行 python /opt/module/datax/bin/datax.py /opt/module/datax/job/job.json 更多job.json配置文件在&#xff1a; 生成的DataX配置文件 java -jar datax-config-genera…

数智教育创新如何向未来?腾讯云与你探索革新之路

引言 随着科技革命的快速发展&#xff0c;掀起教育领域的变革&#xff0c;新理念、新技术、新模式、新应用正不断涌现&#xff0c;正塑造着教育的未来形态。未来科技还将如何赋能教育创新&#xff1f; 5月31日&#xff0c;由腾讯云TVP 与西安电子科技大学联合举办的「数智教育的…

深入理解 Java 中的 synchronized 代码块

目录 前言 一、synchronized的工作原理 二、使用synchronized代码块的场景 三、编写synchronized代码块的最佳实践 四、何时使用 synchronized 代码块&#xff1f; 同步&#xff1a; 不同步&#xff1a; 五、Demo讲解 1.使用synchronized代码块减小锁的粒度&#xff0c…

51 USART数据收发

1.0 USART实现单个数据收发 串口启动之前需要对串口进行初始化&#xff0c;主要是设置产生波特率的定时器1&#xff0c;使用串口的工作方式还是中断的工作方式具体的配置步骤如下所示。 注&#xff1a; 1&#xff1a; 确定TMOD &#xff08;定时器模式寄存器&#xff09; 确…

2021年9月电子学会青少年软件编程 中小学生Python编程等级考试三级真题解析(判断题)

2021年9月Python编程等级考试三级真题解析 判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 26、readline()执行结果为字符串&#xff0c;readlines()执行结果为列表 答案&#xff1a;对 考点分析&#xff1a;考查文件读操作&#xff0c;readli…

省去烦恼!轻松实现一台电脑登录多个微信号的秘诀揭秘!

你知道如何在同一台电脑上登录多个微信号&#xff0c;并实现聚合聊天吗&#xff1f; 今天&#xff0c;我将分享一个多微管理神器——个微管理系统&#xff0c;帮助你解决这一问题&#xff01; 1、多号同时登录&#xff0c;聚合聊天 无论你有多少个微信号&#xff0c;都可以一…

yolov8通过训练完成的模型生成图片热力图--论文需要

源代码来自于网络 使用pytorch_grad_cam&#xff0c;对特定图片生成热力图结果。 安装热力图工具 pip install pytorch_grad_cam pip install grad-cam# get_params中的参数&#xff1a; # weight&#xff1a; # 模型权重文件&#xff0c;代码默认是yolov8m.pt # c…

【机器学习】集成学习方法:Bagging与Boosting的应用与优势

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、集成学习的定义二、Bagging方法1. 随机森林&#xff08;Random Forest&#xff09;2. 其他Bagging方法 二、Boosting方法1. 梯度提升树&#xff08;Gradient Boosting Machine, GBM&#xff09;解释GBM的基本原理和…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 特惠寿司(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 特惠寿司(100分) 🌍 评测功能需要订阅专栏后私信联系清隆解…

9. 文本三剑客之awk

文章目录 9.1 什么是awk9.2 awk命令格式9.3 awk执行流程11.4 行与列11.4.1 取行11.4.2 取列 9.1 什么是awk 虽然sed编辑器是非常方便自动修改文本文件的工具&#xff0c;但其也有自身的限制。通常你需要一个用来处理文件中的数据的更高级工具&#xff0c;它能提供一个类编程环…

【二】【动态规划NEW】91. 解码方法,62. 不同路径,63. 不同路径 II

91. 解码方法 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; ‘A’ -> “1” ‘B’ -> “2” … ‘Z’ -> “26” 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法&#xff…

利用74HC165实现8路并行输入口的扩展

代码&#xff1a; #include <mega16.h>// Declare your global variables here #define hc165_clk PORTB.0 #define hc165_lp PORTB.1 #define hc165_out PINB.2unsigned char read_hc165(void) {unsigned char data0,i,temp0x80;hc165_lp0;hc165_lp1; for(i0;i<7;i)…

Git 基础操作(一)

Git 基础操作 配置Git 安装完Git后&#xff0c;首先要做的事情是设置你的 用户名 和 e-mail 地址。这样在你向仓库提交代码的时候&#xff0c;就知道是谁提交的&#xff0c;以及提交人的联系方式。 配置用户名和邮箱 使用git config [--global] user.name "你的名字&qu…

碳中和研究院OLED透明屏2x2整机项目方案

一、项目背景 随着全球气候变化和环境问题的日益严重&#xff0c;碳中和成为各国政府和企业的重要议题。为了响应这一趋势&#xff0c;黑龙江碳中和研究院计划引入先进的OLED透明屏技术&#xff0c;以展示其研究成果和碳中和理念。本项目旨在为该研究院提供一套高质量的OLED透明…

干部选拔任用的六条原则

在干部选拔任用的过程中&#xff0c;为确保选拔出的干部能够真正符合党和人民的期望&#xff0c;必须遵循以下六条原则&#xff1a; 一、党管干部原则 党管干部原则是指在整个干部选拔任用过程中&#xff0c;党要发挥总揽全局、协调各方的领导作用&#xff0c;确保选拔出的干…

pytorch 加权CE_loss实现(语义分割中的类不平衡使用)

加权CE_loss和BCE_loss稍有不同 1.标签为long类型&#xff0c;BCE标签为float类型 2.当reduction为mean时计算每个像素点的损失的平均&#xff0c;BCE除以像素数得到平均值&#xff0c;CE除以像素对应的权重之和得到平均值。 参数配置torch.nn.CrossEntropyLoss(weightNone,…

算法01 递推算法及相关问题详解【C++实现】

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…

【机器学习】LightGBM: 优化机器学习的高效梯度提升决策树

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 LightGBM: 优化机器学习的高效梯度提升决策树引言一、LightGBM概览二、核心技术…