兰州网站建设加王道下拉鞍山做网站的
web/
2025/9/26 22:58:32/
文章来源:
兰州网站建设加王道下拉,鞍山做网站的,wordpress 多个主题,江苏建设人才无纸化考核网站Visitor设计模式访问元素方法的问题 GPT给出的答案寻找灵感前置声明Element层次的实例Visitor interface的声明Element interface的声明Element实际类的声明及实现实现一个Visitor客户端代码 实战测试结果 针对C来说#xff0c;若要实现Visitor设计模式#xff0c;则会面临循… Visitor设计模式访问元素方法的问题 GPT给出的答案寻找灵感前置声明Element层次的实例Visitor interface的声明Element interface的声明Element实际类的声明及实现实现一个Visitor客户端代码 实战测试结果 针对C来说若要实现Visitor设计模式则会面临循环声明问题。
Element接口的声明中需要Visitor的声明Visitor接口需要Element……若均使用include宏则会导致至少一方无定义进一步导致“不完全类型”错误。 但如果按照常规仅在Visitor的声明上方采用单行声明方式添加Element实例的声明就无法调用各个Element内部的特有方法了。
GPT给出的答案
#include iostreamusing 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.hclass 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.hvoid 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.hclass RealVisitor: public Visitor
{
public:void visit(ClassA a) override;void visit(ClassB b) override;
};RealVisitor.cpp实现它
#include RealVisitor.h
#include Nodes.hvoid 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.hint main()
{ClassA a;ClassB b;RealVisitor v;a.accept(v);b.accept(v);Base ca;c.accept(v);
}测试结果
a
aaa:1
b
bbb:2
a
aaa:1可以看见即使以Base类的身份调用accept利用双重分发机制也可以正确地调用Visitor的正确处理方法Visitor的方法也可以正确地调用Element的方法。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81351.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!