新闻中心

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

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

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

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

访问者模式的核心思想

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

关键角色包括:

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

基本实现步骤

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

1. 定义元素接口

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

class Shape;
<p>class ShapeVisitor {
public:
virtual void visitCircle(const Circle<em> circle) = 0;
virtual void visitRectangle(const Rectangle</em> rectangle) = 0;
virtual ~ShapeVisitor() = default;
};</p><p>class Shape {
public:
virtual void accept(ShapeVisitor& visitor) const = 0;
virtual ~Shape() = default;
};

2. 实现具体元素

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

Tunee AI Tunee AI

新一代AI音乐智能体

Tunee AI 1104 查看详情 Tunee AI
class Circle : public Shape {
public:
    void accept(ShapeVisitor& visitor) const override {
        visitor.visitCircle(this);
    }
    double radius() const { return 1.0; }
};
<p>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";
    }
<pre class="brush:php;toolbar:false;">void visitRectangle(const Rectangle* rectangle) override {
    std::cout << "Drawing a rectangle " 
              << rectangle->width() << "x" << rectangle->height() << "\n";
}

};

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

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

};

使用方式示例

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

std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>());
shapes.push_back(std::make_unique<Rectangle>());
<p>DrawVisitor drawVisitor;
S*eVisitor s*eVisitor;</p><p>for (const auto& shape : shapes) {
shape->accept(drawVisitor);   // 执行绘制
}</p><p>for (const auto& shape : shapes) {
shape->accept(s*eVisitor);   // 执行保存
}

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

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

以上就是c++++如何实现访问者设计模式_c++在不修改类的情况下添加新操作的详细内容,更多请关注其它相关文章!


# json  # 如何登录建设招标网站  # 现在做网站怎么推广  # 定海区营销推广哪个好点  # 摄影网站建设知识  # 译为  # 如何将  # 并在  # 适用于  # 只需  # 如何实现  # 器中  # 情况下  # 子类  # 数据结构  # win  # c++  # js  # 武汉家装网站优化排名  # 推广营销的最佳方法  # 免费关键词查搜索排名  # 百姓网网站建设  # 金属加工网站建设  # 普洱营销推广策划 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: c++ dfs和bfs代码 c++深度广度优先搜索算法  Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】  为什么我的微信朋友圈看不到别人的更新_微信朋友圈更新显示异常解决方法  德邦快递查询平台 德邦快递物流信息查询入口  AI泡沫首次被“刺破”:GPU十年都无法存活!  2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享  小红书商家版怎样在笔记嵌入商品卡路径_小红书商家版在笔记嵌入商品卡路径【挂载教程】  小米汽车11月交付量突破40000台!雷军:将继续努力  Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】  微信聊天记录怎么加密_微信聊天记录加密方法  在J*a项目里如何构建对象之间的契约_接口约束的实际落地  12306选座如何查看座位示意图_12306座位示意图解读与使用  漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址  如何在Promise链中有效终止错误处理后的执行  可靠CSGO开箱平台解析 CSGO开箱网合集  押井守高度称赞《辐射4》:玩了八年都停不下来!  必由学网页版入口 必由学官方平台直接访问  LINUX的perf命令入门_LINUX官方性能分析工具的使用与解读  深入理解Google Cloud Datastore查询:祖先路径与数据一致性  想当下一个《2077》?《心之眼》Steam评价升至"多半好评"  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  Python多版本共存与虚拟环境管理深度指南  C++ explicit关键字防止隐式转换_C++构造函数安全规范  Typer应用中动态命令行参数的解析与处理  Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】  汽水音乐在线解析 汽水音乐在线解析入口  学习通在线学习平台 学习通网页版直接进入课程中心  处理嵌套交互式控件:前端可访问性指南  excel怎么制作工资条 excel快速生成工资条的方法  小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口  mcjs网页版在线存档 mcjs云存档登录入口  零跑汽车11月交付量达70327台 实现连续9个月正增长  Angular响应式表单:实现提交后表单及按钮的禁用与只读化  Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口  mcjs网页版流畅运行 mcjs低配电脑畅玩入口  zookeeper 都有哪些功能?  动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道  AO3官方可用镜像 Archive of Our Own网页版最新入口  优化HTML表单样式:解决输入框焦点跳动与元素间距问题  理解Python模块与全局变量的作用域管理  蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】  Golang如何实现状态模式管理对象状态_Golang State模式实现技巧  谷歌邮箱注册显示错误Gmail服务器异常与延迟处理  在React函数组件中利用原生HTML5进行邮箱地址验证  抖音怎么赚钱_抖音创作者变现方法与途径指南  Mac怎么使用表情符号_Mac Emoji快捷键面板  深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现  css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容  MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复  windows10怎么查看硬盘序列号_windows10硬盘id查询命令 

搜索