《C++新经典设计模式》之第20章 访问者模式

《C++新经典设计模式》之第20章 访问者模式

        • 访问者模式.cpp

访问者模式.cpp
#include <iostream>
#include <list>
#include <memory>
using namespace std;// 提供一个作用于某对象结构中的各元素的操作表示,便可以在不改变各元素类的前提下定义(扩展)作用于这些元素的新操作
// 允许一个或多个操作应用于一组对象上,使对象本身和操作解耦
// 5种角色
// Visitor(抽象访问者),为对象结构中的元素声明访问接口
// ConcreteVisitor(具体访问者),实现接口
// Element(抽象元素),定义Accept方法,形参通常为Visitor指针
// ConcreteElement(具体元素),实现Accept方法,该方法中调用ConcreteVisitor的访问操作,实现元素操作
// ObjectStructure(对象结构),元素集合,存放元素对象并提供遍历其内部元素的接口,一般用于同一批元素的相同操作namespace ns1
{class Medicine // 药品父类{public:virtual ~Medicine() {}virtual string getMdcName() const = 0; // 药品名称virtual float getPrice() const = 0;    // 药品总价格,单位:元};class M_asplcrp : public Medicine // 药品:阿司匹林肠溶片{public:string getMdcName() const override{return "Aspirin enteric-coated tablets";}float getPrice() const override{return 46.8f; // 为简化代码,直接给出药品总价而不单独强调药品数量了,比如该药品医生给开了两盒,一盒是23.4,那么这里直接返回两盒的价格}};class M_fftdnhsp : public Medicine // 药品:氟伐他汀钠缓释片{public:string getMdcName() const override{return "Fluvastatin sodium sustained-release tablets";}float getPrice() const override{return 111.3f; // 三盒的价格}};class M_dlx : public Medicine // 药品:黛力新{public:string getMdcName() const override{return "Deanxit";}float getPrice() const override{return 122.0f; // 两盒的价格}};class MedicineProc // 针对药品的处理相关类{list<shared_ptr<Medicine>> m_mdclist; // 药品列表,记录着药品单上的所有药品public:// 增加药品到药品列表中void addMedicine(const shared_ptr<Medicine> &p_mdc) { m_mdclist.push_back(p_mdc); }// 针对费用缴纳和取药所做的处理动作void procAction(const string &strvisitor) // strvisitor代表拿到了药品单的人,不同的人拿到药品单所要做的处理也不同{if (strvisitor == "Toll collector") // 收费人员要根据药品单向我(患者)收取费用{float totalcost = 0.0f; // 总费用for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter){float tmpprice = (*iter)->getPrice();totalcost += tmpprice;cout << "yao: " << (*iter)->getMdcName() << ", price: " << tmpprice << endl;}cout << "total price: " << totalcost << ", Toll collector charges a fee!" << endl;}else if (strvisitor == "Drug taking personnel") // 取药人员要根据药品单为我拿药for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)cout << "Drug taking personnel give " << (*iter)->getMdcName() << " to me!" << endl;else if (strvisitor == "dietitian")cout << "Nutritionist suggested: match coarse grains with staple foods and eat meat properly!" << endl;else if (strvisitor == "Fitness coach")cout << "The fitness coach suggested: do more aerobic exercises such as jogging (35 minutes), warm up before and after jogging, avoid anxiety, avoid staying up late, and take a bed rest before 22:30!" << endl;}};
}namespace ns2
{class Visitor; // 类前向声明class Medicine // 药品父类{public:virtual ~Medicine() {}virtual void Accept(shared_ptr<Visitor> &pvisitor) = 0; // 这里的形参是访问者父类指针public:virtual string getMdcName() = 0; // 药品名称virtual float getPrice() = 0;    // 药品总价格,单位:元};class M_asplcrp : public Medicine // 药品:阿司匹林肠溶片{public:string getMdcName() override { return "Aspirin enteric-coated tablets"; }float getPrice() override { return 46.8f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class M_fftdnhsp : public Medicine // 药品:氟伐他汀钠缓释片{public:string getMdcName() override { return "Fluvastatin sodium sustained-release tablets"; }float getPrice() override { return 111.3f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class M_dlx : public Medicine // 药品:黛力新{public:string getMdcName() override { return "Deanxit"; }float getPrice() override { return 122.0f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class Visitor // 访问者父类{public:virtual ~Visitor() {}virtual void Visit_elm_asplcrp(M_asplcrp *pelem) = 0;   // 访问元素:阿司匹林肠溶片virtual void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) = 0; // 访问元素:氟伐他汀钠缓释片virtual void Visit_elm_dlx(M_dlx *pelem) = 0;           // 访问元素:黛力新以下几个接口的名字都叫Visit(成员函数重载)// virtual void Visit(M_asplcrp* pelem) = 0;   //访问元素:阿司匹林肠溶片// virtual void Visit(M_fftdnhsp* pelem) = 0;  //访问元素:氟伐他汀钠缓释片// virtual void Visit(M_dlx* pelem) = 0;       //访问元素:黛力新};class Visitor_SFRY : public Visitor // 收费人员访问者子类{float m_totalcost = 0.0f; // 总费用public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}void Visit_elm_dlx(M_dlx *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}// 返回总费用float getTotalCost() const { return m_totalcost; }};class Visitor_QYRY : public Visitor // 取药人员访问者子类{public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}void Visit_elm_dlx(M_dlx *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}};class Visitor_YYS : public Visitor // 营养师访问者子类{public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;}void Visit_elm_dlx(M_dlx *pelem) override{cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;}};// 各个药品子类Accept方法的实现体代码void M_asplcrp::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_asplcrp(this);}void M_fftdnhsp::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_fftdnhsp(this);}void M_dlx::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_dlx(this);}class ObjectStructure // 对象结构{list<shared_ptr<Medicine>> m_mdclist; // 药品列表public:// 增加药品到药品列表中void addMedicine(const shared_ptr<Medicine> &p_mdc){m_mdclist.push_back(p_mdc);}void procAction(shared_ptr<Visitor> &pvisitor){for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)(*iter)->Accept(pvisitor);}};
}namespace ns3
{class Medicine; // 类前向声明class Visitor   // 访问者父类{public:virtual ~Visitor() {}virtual void Visit(Medicine *const pelem) = 0;};class Medicine // 药品父类{public:virtual ~Medicine() {}virtual void Accept(shared_ptr<Visitor> &pvisitor) { pvisitor->Visit(this); }public:virtual string getMdcName() const = 0; // 药品名称virtual float getPrice() const = 0;    // 药品总价格,单位:元};class M_asplcrp : public Medicine // 药品:阿司匹林肠溶片{public:string getMdcName() const override { return "Aspirin enteric-coated tablets"; }float getPrice() const override { return 46.8f; }};class M_fftdnhsp : public Medicine // 药品:氟伐他汀钠缓释片{public:string getMdcName() const override { return "Fluvastatin sodium sustained-release tablets"; }float getPrice() const override { return 111.3f; }};class M_dlx : public Medicine // 药品:黛力新{public:string getMdcName() const override { return "Deanxit"; }float getPrice() const override { return 122.0f; }};class Visitor_SFRY : public Visitor // 收费人员访问者子类{float m_totalcost = 0.0f; // 总费用public:void Visit(Medicine *const m) override{float tmpprice = m->getPrice();m_totalcost += tmpprice;cout << "yao: " << m->getMdcName() << ", price: " << tmpprice << endl;}float getTotalCost() const { return m_totalcost; } // 返回总费用};class Visitor_QYRY : public Visitor // 取药人员访问者子类{public:void Visit(Medicine *const m) override{cout << "Drug taking personnel give " << m->getMdcName() << " to me!" << endl;}};class Visitor_YYS : public Visitor // 营养师访问者子类{public:void Visit(Medicine *const m) override{cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;}};class ObjectStructure // 对象结构{list<shared_ptr<Medicine>> m_mdclist; // 药品列表public:// 增加药品到药品列表中void addMedicine(const shared_ptr<Medicine> &p_mdc){m_mdclist.push_back(p_mdc);}void procAction(shared_ptr<Visitor> &pvisitor){for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)(*iter)->Accept(pvisitor);}};
}int main()
{
#if 0using namespace ns1;shared_ptr<Medicine> pm1(new M_asplcrp());  // 药品阿司匹林肠溶片shared_ptr<Medicine> pm2(new M_fftdnhsp()); // 药品氟伐他汀钠缓释片shared_ptr<Medicine> pm3(new M_dlx());      // 药品黛力新MedicineProc mdcprocobj;mdcprocobj.addMedicine(pm1);mdcprocobj.addMedicine(pm2);mdcprocobj.addMedicine(pm3);mdcprocobj.procAction("Toll collector");mdcprocobj.procAction("Drug taking personnel");
#endif#if 1// using namespace ns2;using namespace ns3;shared_ptr<Medicine> mdc_asplcrp(new M_asplcrp());shared_ptr<Medicine> mdc_fftdnhsp(new M_fftdnhsp());shared_ptr<Medicine> mdc_dlx(new M_dlx());// 各个元素子类调用Accept接受访问者的访问,就可以实现访问者要实现的功能shared_ptr<Visitor> visitor_sf(new Visitor_SFRY()); // 收费人员访问者子类,里面承载着向我(患者)收费的算法mdc_asplcrp->Accept(visitor_sf);                    // 累加“阿司匹林肠溶片”的价格mdc_fftdnhsp->Accept(visitor_sf);                   // 累加“氟伐他汀钠缓释片”的价格mdc_dlx->Accept(visitor_sf);                        // 累加“黛力新”的价格cout << "total price: " << dynamic_pointer_cast<Visitor_SFRY>(visitor_sf)->getTotalCost() << ", the toll collector charged me!" << endl;shared_ptr<Visitor> visitor_qy(new Visitor_QYRY()); // 取药人员访问者子类,里面承载着向我发放药品的算法mdc_asplcrp->Accept(visitor_qy);                    // 我取得“阿司匹林肠溶片”mdc_fftdnhsp->Accept(visitor_qy);                   // 我取得“氟伐他汀钠缓释片”mdc_dlx->Accept(visitor_qy);                        // 我取得“黛力新”shared_ptr<Visitor> visitor_yys(new Visitor_YYS()); // 营养师访问者子类,里面承载着为我配置营养餐的算法mdc_asplcrp->Accept(visitor_yys);                   // 营养师针对治疗预防血栓药“阿司匹林肠溶片”给出的对应的营养餐建议mdc_fftdnhsp->Accept(visitor_yys);                  // 营养师针对降血脂药“氟伐他汀钠缓释片”给出的对应的营养餐建议mdc_dlx->Accept(visitor_yys);                       // 营养师针对治疗神经紊乱药“黛力新”给出的对应的营养餐建议shared_ptr<ObjectStructure> objstruc(new ObjectStructure());objstruc->addMedicine(mdc_asplcrp);objstruc->addMedicine(mdc_fftdnhsp);objstruc->addMedicine(mdc_dlx);objstruc->procAction(visitor_yys); // 将一个访问者对象(visitor_yys)应用到一批元素上,以实现对一批元素进行同一种(营养方面的)操作
#endifcout << "Over!\n";return 0;
}

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

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

相关文章

springboot(ssm寝室小卖部系统 宿舍小商店网站Java(codeLW)

springboot(ssm寝室小卖部系统 宿舍小商店网站Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#x…

【力扣100】7.无重复字符的最长子串

添加链接描述 class Solution:def lengthOfLongestSubstring(self, s: str) -> int:# 思路是使用队列&#xff0c;加入一次取一个最大值&#xff0c;然后如果重复&#xff0c;则队列出到没有重复值位置# 但是这个队列其实使用数组实现的strlist[]temp0result0if len(s)0:re…

字符串指令集

字符串指令的格式 例子1就成功发送了指令 例子2就是发送的字符串有误 查询当前位置就会在附加信息中返回当前座位的坐标 第一个指令的参数就是闪灯的两个参数 如第一个示例就是10ms On Time 第二个就是Off Time 使用标准库来接收字符串命令 字符串指令的接收 因为一个指令就是…

科技改变旅游,道观漫游可视化:智能化管理助力道观游览

道观漫游可视化是一种通过技术手段实现道观游览的可视化展示方式&#xff0c;让游客能够更加直观地了解道观的历史、文化和建筑特色。 随着旅游业的不断发展&#xff0c;道观漫游可视化已经成为了旅游行业中的一个重要方向&#xff0c;吸引了越来越多的游客前来体验。 道观漫游…

打死都不要进外包,看看我在阿里外包的2年...

我18年毕业于一个普通二本学校&#xff0c;是一个很不出名的小本科。大学期间专业知识也没有去认真的学习&#xff0c;所以毕业的时候就随便找了一份工作&#xff0c;在一个小公司做功能测试。 记得那时候薪资大概是6k左右&#xff0c;因为是在工厂&#xff0c;工作环境很差&a…

《Spring Cloud Alibaba 从入门到实战》理论知识篇

基础知识篇 理论篇 俗话说&#xff0c;没有最好的架构&#xff0c;只有最合适的架构。 微服务架构也是随着信息产业的发展而出现的最有普遍适用性的一套架构模式。 通常来说&#xff0c;我们认为架构发展历史经历了这样一个过程&#xff1a;单体架构 -> SOA 面向服务架构 …

springboot智慧导诊系统源码:根据患者症状匹配挂号科室

一、系统概述 医院智慧导诊系统是在医疗中使用的引导患者自助就诊挂号&#xff0c;在就诊的过程中有许多患者不知道需要挂什么号&#xff0c;要看什么病&#xff0c;通过智慧导诊系统&#xff0c;可输入自身疾病的症状表现&#xff0c;或选择身体部位&#xff0c;在经由智慧导诊…

微型5G智能网关助力打造智能清洁机器人

智能机器人不断融入我们的生活&#xff0c;提供了越来越多样化的服务&#xff0c;例如专用于卫生清洁的机器人&#xff0c;就已经广泛应用于酒店、体育馆、大型商场、写字楼、工地等各种场景&#xff0c;相较于人工&#xff0c;机器人在此类具有高度重复性、劳动量大的工作中具…

C++作业6

以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&…

用23种设计模式打造一个cocos creator的游戏框架----(五)工厂方法模式

1、模式标准 模式名称&#xff1a;工厂方法模式 模式分类&#xff1a;创建型 模式意图&#xff1a;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 结构图&#xff1a; 适用于&#xff1a; 1、当一个类不知道它…

failed to install plugin grafana 插件安装失败

升级时忽略plugins 权限问题&#xff0c;导致安装插件失败&#xff01;调整权限即可

042:el-table表格表头自定义高度(亲测好用)

第042个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Shrio 安全框架

目录 前言 1.介绍 2.整合 Shiro 到 Spring Boot 3.Shiro 相关配置 总结 前言 几乎所有涉及用户的系统都需要进行权限管理&#xff0c;权限管理涉及到一个系统的安全。Spring Boot 的安全框架整合方案中还有一个璀璨的明珠&#xff1a;Shrio。 1.介绍 Shiro是一款由Java 编…

信道复用技术

目录 一、频分复用FDM&#xff08;Frequency Division Multiplexing&#xff09; 二、波分复用 WDM&#xff08;Wavelength Division Multiplexing&#xff09; 三、时分复用TDM&#xff08;Time Division Multiplexing&#xff09; 四、统计时分复用 STDM&#xff08;Statisti…

双通道5V高细分步进电机驱动芯片应用于摇头机,X,Y控制,聚焦控制,CAMERA云台控制等产品上的芯片选型分析

双通道5V高细分步进电机驱动芯片GC6106&#xff0c;GC6107&#xff0c;GC6119&#xff0c;GC6151&#xff0c;GC6236&#xff0c;GC6225&#xff0c;GC6129&#xff0c;电压范围3~5.5V&#xff0c;最大持续电流可达0.6A左右。可应用于摇头机&#xff0c;X,Y控制&#xff0c;聚焦…

安装vue环境

1.Hello Vue.js <script src"https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>/*引入js文件 */ <script> new Vue({ /* 创建一个对象&#xff0c;两个属性。 */ el: #app, data: { message: Hello Vue.js! }, methods: { details: f…

C++使用模板的注意事项

两点注意事项 自动推导类型&#xff0c;必须推导出一致的数据类型T&#xff0c;才可以使用模板必须要确定出T的数据类型&#xff0c;才可以使用 #include<iostream> using namespace std;//第一点必须一致的数据类型 template <class T> void myswap(T& a, T…

基于AIS数据的船舶密度计算与规律研究

参考文献&#xff1a;[1]陈晓. 基于AIS数据的船舶密度计算与规律研究[D].大连海事大学,2021.DOI:10.26989/d.cnki.gdlhu.2020.001129. 谢谢姐姐的文章&#xff01; 网格化AIS数据 网格化 AIS 数据是处理和分析船舶轨迹数据的一种有效方法&#xff0c;特别是当涉及到密度计算和…

C++_对C数据类型的扩展

结构体 c中定义结构体变量&#xff0c;可以省略struct关键字 c结构提重可以直接定义函数&#xff0c;谓之成员函数&#xff08;方法&#xff09; #include <iostream> using namespace std; struct stu {int num;char name[24];void price(void) {cout << "…

Vue3+Antd实现弹框显示内容并加入复制按钮

使用Vue3antd实现点击弹框出现内容并可复制内容的功能&#xff1a; HTML部分&#xff1a; <a-button type"primary" click"showModel">打开弹框 </a-button><!-- ok 是弹框中确定按钮的操作&#xff0c;cancel 是弹框中取消按钮的操作 --…