Visitor设计模式访问元素方法的问题

Visitor设计模式访问元素方法的问题

  • GPT给出的答案
  • 寻找灵感
    • 前置声明Element层次的实例
    • Visitor interface的声明
    • Element interface的声明
    • Element实际类的声明及实现
    • 实现一个Visitor
    • 客户端代码
  • 实战
  • 测试结果

针对C++来说,若要实现Visitor设计模式,则会面临循环声明问题。

Element接口的声明中,需要Visitor的声明;Visitor接口需要Element……若均使用include宏则会导致至少一方无定义,进一步导致“不完全类型”错误。
但如果按照常规,仅在Visitor的声明上方采用单行声明方式添加Element实例的声明,就无法调用各个Element内部的特有方法了。

GPT给出的答案

#include <iostream>using namespace std;class Employee;
class HourlyEmployee;class IVisitor {
public:virtual void Visit(HourlyEmployee&) = 0;
};class Employee {
public:virtual void Accept(IVisitor& visitor) = 0;
};class HourlyEmployee : public Employee {
public:void Accept(IVisitor& visitor) override {visitor.Visit(*this);}int HourlyMethod() {return 0;}
};class PayrollVisitor : public IVisitor {
public:void Visit(HourlyEmployee& employee) override {cout << employee.HourlyMethod() << endl;}
};int main() {HourlyEmployee hourly_employee;PayrollVisitor payroll_visitor;hourly_employee.Accept(payroll_visitor);
}

源码存在一些问题,已修改,这个文件是可以正常编译的。

寻找灵感

从整个源码结构来看,按顺序分为四个部分

前置声明Element层次的实例

在这里插入图片描述
这一部分是为了让Visitor接口能正确声明

Visitor interface的声明

C++中不存在接口的概念,用抽象类模拟。(也就是带有纯虚函数)
在这里插入图片描述

Element interface的声明

在这里插入图片描述

Element实际类的声明及实现

在这里插入图片描述
当然在实际项目中,会把声明和定义分开。

实现一个Visitor

在这里插入图片描述

客户端代码

在这里插入图片描述

实战

基于上面的分析,我们可以将整个实现放在不同文件中。
目录结构:
在这里插入图片描述
Nodes.h中,声明Element层次

#pragma once#include "Visitor.h"class Base
{
public:virtual void accept(Visitor& v) = 0;
};class ClassA:public Base
{
public:ClassA() {}void accept(Visitor& v) override;int getid();
};class ClassB:public Base
{
public:ClassB() {}void accept(Visitor& v) override;int getidd();
};

注意:在Element层次的头文件中include Visitor接口的声明

Nodes.cpp中,实现这些Element

#include "Nodes.h"void ClassA::accept(Visitor& v)
{v.visit(*this);
}void ClassB::accept(Visitor& v)
{v.visit(*this);
}int ClassA::getid()
{return 1;
}int ClassB::getidd()
{return 2;
}

Visitor.h中,声明Visitor接口,并在接口前前置声明Element实际类

#pragma once#include <iostream>
using namespace std;class ClassA;
class ClassB;class Visitor
{
public:virtual void visit(ClassA& a) = 0;virtual void visit(ClassB& b) = 0;
};

注意:不要用包含的方式,要直接声明

另起一个文件,用来声明具体的Visitor:
RealVisitor.h

#pragma once#include "Visitor.h"class RealVisitor: public Visitor
{
public:void visit(ClassA& a) override;void visit(ClassB& b) override;
};

RealVisitor.cpp实现它:

#include "RealVisitor.h"
#include "Nodes.h"void RealVisitor::visit(ClassA& a)
{cout << "a\n";cout << "aaa:" << a.getid() << endl;
}void RealVisitor::visit(ClassB& b)
{cout << "b\n";cout << "bbb:" << b.getidd() << endl;
}

注意:实现前务必在cpp文件前方采用include的方式包含Element具体类声明
因为实现Visitor的时候需要调用每个具体类的方法

主函数:main.cpp

#include "Nodes.h"
#include "RealVisitor.h"int main()
{ClassA a;ClassB b;RealVisitor v;a.accept(v);b.accept(v);Base &c=a;c.accept(v);
}

测试结果

a
aaa:1
b
bbb:2
a
aaa:1

可以看见,即使以Base类的身份调用accept,利用双重分发机制,也可以正确地调用Visitor的正确处理方法;Visitor的方法也可以正确地调用Element的方法。

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

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

相关文章

Dinky简介与部署(Docker形式)

Dinky简介与部署(Docker) Dinky 简介 实时即未来&#xff0c;Dinky 为 Apache Flink 而生&#xff0c;让 Flink SQL 纵享丝滑。 Dinky 是一个开箱即用、易扩展&#xff0c;以 Apache Flink 为基础&#xff0c;连接 OLAP 和数据湖等众多框架的一站式实时计算平台&#xff0c;致…

SAP安装笔记

1、准备安装介质&#xff0c;SWPM10SP25&#xff0c;51050829_NW750_JavaExport、SAP_HANA_CLIENT、kernel放到/sapcd/NetWeaver目录下 ​​​​​​​ 进入SWPM10SP25执行./sapinst安装 2、待出现 “Open your browser and paste the following URL address to access the G…

上门家政系统开发|上门预约家政小程序定制系统

随着人们生活水平的提高&#xff0c;对于家政服务的需求也越来越高。上门家政小程序的开发为家政服务商家提供了一个全新的经营和服务渠道。本文将介绍上门家政小程序适合的商家以及其优势。   1. 家政公司   家政公司是最直接受益于上门家政小程序开发的商家。通过开发家政…

企业博客资讯如何高效运营起来?

运营一个高效的企业博客资讯需要综合考虑多个因素&#xff0c;包括内容策划、发布频率、优化推广、互动反馈等。下面将从这些方面介绍如何高效运营企业博客资讯。 如何高效运营企业博客资讯 内容策划 首先&#xff0c;需要制定一个明确的内容策略。确定博客的定位和目标受众…

【C语言】指针进阶(二)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

【UE5 多人联机教程】04-加入游戏

效果 步骤 1. 新建一个控件蓝图&#xff0c;父类为“USC_Button_Standard” 控件蓝图命名为“UMG_Item_Room”&#xff0c;用于表示每一个搜索到的房间的界面 打开“UMG_Item_Room”&#xff0c;在图表中新建一个变量&#xff0c;命名为“Session” 变量类型为“蓝图会话结果…

MB5B在HDB上的性能调优

背景 MB5B是用于查询物料的收发以及现有库存。日常业务查询,通常会按照月份查看某片地区物料的库存以及收发状态。 调优思路 按照客户日常操作的习惯,得到日常操作的数据范围,选出数据量最为突出最有代表性的地区和物料;利用SE30分别运行不同数量级的数据,比如20个门店、…

记一个nginx server_name配置多个域名时的坑

server_name 指令详解 server_name 指令设置基于域名的虚拟主机&#xff0c;⼀个ip的服务器可以配置多个域名。下⾯这些server_name是有效的: server_name domain.com;server_name domain.com www.domain.com;server_name *.domain.com;server_name .domain.com;server_name d…

【ESP32】开发笔记

​ 一、搭建开发环境 开发环境基于Windows操作系统&#xff0c;VSCode编译器&#xff0c;Espressif IDF插件。 1.ESP-IDF SDK及环境 下面两种链接任选其一&#xff0c;建议选择【ESP32】ESP-IDF安装 【ESP32】ESP-IDF安装 【ESP32】Espressif-IDE及ESP-IDF安装 2.【VSCode】…

利用sklearn 实现线性回归、非线性回归

代码&#xff1a; import pandas as pd import numpy as np import matplotlib import random from matplotlib import pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression# 创建虚拟数据 x np.array(r…

Python操作Excel文件,修改Excel样式(openpyxl)

秋风阁-北溪入江流 文章目录 安装依赖库openpyxlopenpyxl的操作加载文件&#xff0c;获取sheet加载文件load_workbook获取sheet 遍历单元格迭代遍历索引遍历 单元格行高和列宽的修改Excel列号与字母的转换Excel行高修改Excel列宽修改 Excel表格文字对齐属性设置修改单元格框线保…

浮标水质监测站现场水质自动监测仪

浮标水质监测站是设立在河流、湖泊、水库、近岸海域等流域内进行现场水质自动监测的监测仪器&#xff0c;是以水质监测仪为核心&#xff0c;运用传感器技术&#xff0c;结合浮标体、电源供电系统、数据传输设备组成的放置于水域内的小型水质监测系统。用于连续自动监测被测水体…

Python的用处到底是什么?(一)

1. 网络爬虫&#xff1a;使用Python的库&#xff0c;如BeautifulSoup&#xff0c;可以轻松地从网页中提取数据。 当涉及到从互联网上收集大量数据时&#xff0c;Python是一个非常强大的语言&#xff0c;它提供了许多用于网络爬虫的库和工具。其中最常用的库之一是BeautifulSou…

DAY3,Qt(完成闹钟的实现,定时器事件处理函数的使用)

1.完成闹钟的实现&#xff0c;到点播报文本框的内容&#xff1b; ---alarm.h---头文件 #ifndef ALARM_H #define ALARM_H#include <QWidget> #include <QTimerEvent> //定时器处理函数类 #include <QTime> //时间类 #include <QPushButton> //按钮…

蓝牙技术|智能照明市场蓬勃发展,蓝牙技术助力市场发展

照明控制系统在商业和工业领域的应用广泛。例如&#xff0c;智能办公楼、商场、工厂等场所&#xff0c;可以通过照明控制系统实现节能和舒适性的提升。预计将从2023年的74亿美元增长到2032年的108亿美元&#xff0c;复合年增长率(CAGR)为4.3%。 随着LED照明技术在市场上的逐渐普…

QT DAY3

1.思维导图 2.完成闹钟的实现 头文件 #include <QTextToSpeech> #include <QTextEdit> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTQLineEdit *edit1new QLineEdit;// QTextEdit *edit2new QTe…

什么是DPA实验,DPA的应用场景行业及可检测的问题要点总结

🏡《电子元器件学习目录》 目录 1,什么是DPA实验2,DPA的起源与应用行业3,DPA的应用场景4,DPA可检测的问题4.1,性能下降4.2,工艺问题4.3,结构问题4.4,可靠性问题4.5,交货检验5,总结1,什么是DPA实验 DPA是Destructive Physical Analysis的缩写,DPA实验又被称为破坏…

java版企业工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

新手小白学习SWAT模型【建模方法、实例应用、高级进阶】

目录 第一部分&#xff1a;SWAT模型实践部分 第二部分&#xff1a;SWAT模型【进阶部分】 更多推荐 【专家】&#xff1a;刘老师【副教授】&#xff0c;北京重点高校资深专家&#xff0c;和美国SWAT软件开发方长期合作&#xff0c;拥有丰富的科研及工程技术经验&#xff0c;长…

【双指针优化DP】CF985E

Problem - 985E - Codeforces 题意&#xff1a; 思路&#xff1a; 首先肯定需要排个序&#xff0c;然后分段DP 但是平常写的分段DP都是n^2的&#xff0c;这里的可以发现单调性&#xff0c;因此考虑双指针转移 这里两个指针都代表两个段的右端点 Code&#xff1a; #includ…