全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++如何实现访问者设计模式_c++在不修改类的情况下添加新操作

访问者设计模式通过分离数据结构与操作,允许在不修改原有类的情况下添加新行为。1. 定义Visitor接口声明对各元素的访问方法;2. 元素类实现accept方法,接收访问者并调用其对应函数;3. 具体访问者实现不同操作逻辑。例如图形类Shape通过accept接受DrawVisitor或SaveVisitor,实现绘制与保存功能,符合开闭原则,适用于结构稳定、行为多变的场景。

在C++中,访问者设计模式允许你在不修改原有类结构的前提下为这些类添加新的操作。这种模式特别适用于类结构相对稳定,但需要频繁增加新行为的场景。

访问者模式的核心思想

将数据结构与作用于其上的操作分离。通过引入一个访问者接口,把对各类对象的操作封装到访问者中,从而避免不断修改原始类来添加功能。

关键角色包括:

  • Visitor(访问者):定义对每个具体元素的访问方法。
  • Element(元素):声明接受访问者的方法,通常为accept(Visitor&)
  • ConcreteElement:实现accept方法,调用访问者的对应函数。
  • ConcreteVisitor:实现具体操作逻辑。

基本实现步骤

假设我们有一组图形类(如圆形、矩形),想在不改动它们的情况下支持“绘制”和“保存”等新操作。

1. 定义元素接口

所有可被访问的类都继承自同一个基类:

class Shape;

class ShapeVisitor { public: virtual void visitCircle(const Circle circle) = 0; virtual void visitRectangle(const Rectangle rectangle) = 0; virtual ~ShapeVisitor() = default; };

class Shape { public: virtual void accept(ShapeVisitor& visitor) const = 0; virtual ~Shape() = default; };

2. 实现具体元素

每个子类实现accept,反向调用访问者对应方法:

class Circle : public Shape {
public:
    void accept(ShapeVisitor& visitor) const override {
        visitor.visitCircle(this);
    }
    double radius() const { return 1.0; }
};

class Rectangle : public Shape { public: void accept(ShapeVisitor& visitor) const override { visitor.visitRectangle(this); } double width() const { return 2.0; } double height() const { return 3.0; } };

3. 创建具体访问者

新增操作只需添加新的访问者类:

class DrawVisitor : public ShapeVisitor {
public:
    void visitCircle(const Circle* circle) override {
        std::cout << "Drawing a circle with radius " << circle->radius() << "\n";
    }
void visitRectangle(const Rectangle* rectangle) override {
    std::cout << "Drawing a rectangle " 
              << rectangle->width() << "x" << rectangle->height() << "\n";
}

};

class SaveVisitor : public ShapeVisitor { public: void visitCircle(const Circle* circle) override { std::cout radius()

void visitRectangle(const Rectangle* rectangle) override {
    std::cout << "Saving rectangle data: "
              << rectangle->width() << "," << rectangle->height() << "\n";
}

};

使用方式示例

客户端代码可以灵活切换不同操作:

std::vector> shapes;
shapes.push_back(std::make_unique());
shapes.push_back(std::make_unique());

DrawVisitor drawVisitor; SaveVisitor saveVisitor;

for (const auto& shape : shapes) { shape->accept(drawVisitor); // 执行绘制 }

for (const auto& shape : shapes) { shape->accept(saveVisitor); // 执行保存 }

这样,每当需要新增功能(比如计算面积、导出JSON),只需写一个新的访问者类,无需改动任何已有Shape相关代码。

基本上就这些。只要类提供了accept接口,后续扩展操作就很方便,符合开闭原则。缺点是如果元素类型经常变动,维护访问者的双分派会变得繁琐。但在结构稳定时,这是解耦数据与行为的有效手段。不复杂但容易忽略细节。


# js  # json  # c++  # win  # 封装  # 子类  # const  # void  # 数据结构  # 继承  # 接口  # class  # public  # 对象  # 只需  # 适用于  # 这是  # 情况下  # 开闭  # 已有  # 你在  # 但在 


相关文章: 学校建站服务器如何选型才能满足性能需求?  台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  家庭建站与云服务器建站,如何选择更优?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  如何有效防御Web建站篡改攻击?  制作企业网站建设方案,怎样建设一个公司网站?  建站之星如何实现PC+手机+微信网站五合一建站?  SQL查询语句优化的实用方法总结  如何在阿里云购买域名并搭建网站?  电商平台网站制作流程,电商网站如何制作?  免费网站制作appp,免费制作app哪个平台好?  威客平台建站流程解析:高效搭建教程与设计优化方案  建站之星如何开启自定义404页面避免用户流失?  如何做网站制作流程,*游戏网站怎么搭建?  如何通过免费商城建站系统源码自定义网站主题与功能?  用v-html解决Vue.js渲染中html标签不被解析的问题  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  简单实现Android验证码  教程网站设计制作软件,怎么创建自己的一个网站?  成都响应式网站开发,dw怎么把手机适应页面变成网页?  如何快速搭建高效香港服务器网站?  建站之星后台密码遗忘如何找回?  已有域名和空间如何搭建网站?  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析  做企业网站制作流程,企业网站制作基本流程有哪些?  西安专业网站制作公司有哪些,陕西省建行官方网站?  如何在云指建站中生成FTP站点?  C++如何使用std::optional?(处理可选值)  如何做静态网页,sublimetext3.0制作静态网页?  如何通过IIS搭建网站并配置访问权限?  内网网站制作软件,内网的网站如何发布到外网?  公司门户网站制作流程,华为官网怎么做?  个人摄影网站制作流程,摄影爱好者都去什么网站?  大型企业网站制作流程,做网站需要注册公司吗?  巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  建站之星展会模版如何一键下载生成?  大连网站设计制作招聘信息,大连投诉网站有哪些?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  网站制作公司,橙子建站是合法的吗?  怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?  如何通过智能用户系统一键生成高效建站方案?  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  如何在腾讯云服务器上快速搭建个人网站?  PHP正则匹配日期和时间(时间戳转换)的实例代码  想学网站制作怎么学,建立一个网站要花费多少? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。