新闻中心
C++如何实现一个访问者模式(Visitor Pattern)_C++设计模式与访问者实现
访问者模式通过双重分发在不修改元素类的前提下扩展操作,由抽象元素、具体元素、抽象访问者、具体访问者和对象结构组成,适用于元素稳定但操作多变的场景,如AST处理,优点是符合开闭原则,缺点是新增元素需修改所有访问者。

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不修改对象结构的前提下,为对象结构中的元素添加新的操作。C++中实现访问者模式的关键在于双重分发(Double Dispatch),通过虚函数机制实现动态调用。
访问者模式的核心组成
访问者模式包含以下几个核心部分:
- 抽象元素(Element):定义一个accept方法,接收访问者对象。
- 具体元素(ConcreteElement):实现accept方法,调用访问者的visit方法。
- 抽象访问者(Visitor):声明一组visit函数,对应不同的元素类型。
- 具体访问者(ConcreteVisitor):实现具体的访问逻辑。
- 对象结构(ObjectStructure):如容器,用于遍历并接受访问者。
代码实现示例
下面是一个简单的C++实现,模拟对不同形状进行“绘制”和“计算面积”的操作:
// 抽象访问者class ShapeVisitor;
// 抽象元素class Shape {public:virtual ~Shape() = default;virtual void accept(ShapeVisitor& visitor) = 0;};
// 具体元素:圆形class Circle : public Shape {public:double radius;Circle(double r) : radius(r) {}
<strong>void accept(ShapeVisitor& visitor) override {</strong>
<strong>visitor.visit(*this);</strong>
<strong>}</strong>};
// 具体元素:矩形class Rectangle : public Shape {public:double width, height;Rectangle(double w, double h) : width(w), height(h) {}
<strong>void accept(ShapeVisitor& visitor) override {</strong>
<strong>visitor.visit(*this);</strong>
<strong>}</strong>};
// 抽象访问者class ShapeVisitor {public:virtual ~ShapeVisitor() = default;virtual void visit(Circle& circle) = 0;virtual void visit(Rectangle& rectangle) = 0;};
// 具体访问者:绘图class DrawVisitor : public ShapeVisitor {public:void visit(Circle& circle) override {std::cout }
<strong>void visit(Rectangle& rectangle) override {</strong>
<strong>std::cout << "绘制宽 " << rectangle.width << " 高 " << rectangle.height << " 的矩形\n";</strong>
<strong>}</strong>};
// 具体访问者:计算面积class AreaVisitor : public ShapeVisitor {public:double totalArea = 0.0;
<strong>void visit(Circle& circle) override {</strong>
<strong>double area = 3.14159 * circle.radius * circle.radius;</strong>
<strong>std::cout << "圆形面积: " << area << "\n";</strong>
<strong>totalArea += area;</strong>
<strong>}</strong>
<strong>void visit(Rectangle& rectangle) override {</strong>
<strong>double area = rectangle.width * rectangle.height;</strong>
<strong>std::cout << "矩形面积: " << area << "\n";</strong>
<strong>totalArea += area;</strong>
<strong>}</strong>};
// 使用示例int main() {std::vector<:unique_ptr>> shapes;shapes.push_back(std::make_unique
<strong>DrawVisitor drawVisitor;</strong>
<strong>AreaVisitor areaVisitor;</strong>
<strong>for (auto& shape : shapes) {</strong>
<strong>shape->accept(drawVisitor);</stron
g>
<strong>}</strong>
<strong>for (auto& shape : shapes) {</strong>
<strong>shape->accept(areaVisitor);</strong>
<strong>}</strong>
<strong>std::cout << "总面积: " << areaVisitor.totalArea << "\n";</strong>
<strong>return 0;</strong>}
使用场景与优缺点
访问者模式适合以下情况:
- 需要对一个对象结构中的多种元素执行不同的操作,且希望将操作分离。
- 元素类相对稳定,但操作经常扩展。
- 避免在元素类中不断添加新方法导致职责膨胀。
优点:
- 符合开闭原则:新增操作只需添加新的访问者。
- 集中相关操作,便于维护。
缺点:
- 增加新元素类型时,所有访问者都要修改。
- 破坏封装性:访问者可能需要访问元素的内部数据。
- 代码复杂度提高,理解成本上升。
基本上就这些。访问者模式在编译器、AST处理、UI控件遍历等场景中较为常见,合理使用能提升系统扩展性。
以上就是C++如何实现一个访问者模式(Visitor Pattern)_C++设计模式与访问者实现的详细内容,更多请关注其它相关文章!
# 是一种
# 英文网站外贸seo
# 江西网站优化推广费用
# 深泽海外网站推广报价
# 西藏银川网站推广
# 营销个人微信推广软文
# 线上运营推广整合营销
# 常州seo公司推荐14火星
# 汕头网站推广营销
# 男装电商营销推广规划
# 郑州免费优化网站
# 都要
# ai
# 开闭
# 前提下
# 几个
# 边缘
# 是一个
# 遍历
# 如何实现
# 游戏开发
# 封装性
# c++
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
uc手机浏览器网页版入口 uc浏览器手机版便捷登录首页
漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口
抖音怎么赚钱_抖音创作者变现方法与途径指南
QQ邮箱网页版登录入口 QQ邮箱官方在线使用平台
QQ邮箱网页版邮箱入口 QQ邮箱官方登录平台
如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!
聚水潭ERP登录页面入口 聚水潭ERP官网登录界面
win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法
Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置
在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案
苹果手机如何防止被恶意App追踪
Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区
b站如何看历史记录_b站观看历史找回方法
J*aScript中正确使用querySelectorAll与复杂CSS选择器
Python:递归比较文件夹内容并找出特定类型文件的差异
在Blazor WebAssembly应用中动态注入客户端特定指标代码的策略
React Hooks最佳实践:动态组件状态管理的组件化方案
TikTok国际版官网直达_TikTok国际版官网直达进入在线观看
TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法
如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略
必由学官方登录入口 必由学教师学生账号快速访问
c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学
Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法
钉钉视频会议画面卡顿如何解决 钉钉会议画面优化方法
c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
QQ邮箱登录官网首页 腾讯QQ邮箱网页入口
Golang如何使用const iota_Go iota常量计数器讲解
AO3中文官网链接_AO3网页版稳定镜像站
Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址
印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】
12306选座如何查看座位示意图_12306座位示意图解读与使用
QQ邮箱在线登录平台 QQ邮箱个人邮箱网页版入口
126邮箱账号注册 电脑版登录入口
AO3最新官网入口公告_2025AO3镜像站实时查询方法
Composer如何处理Git子模块(submodule)依赖_Composer与Git Submodule的对比与选择
蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版
动漫花园资源网使用步骤_动漫花园资源网下载流程
凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
如何仅使用CSS更改登录界面背景图像图标的颜色
Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】
QQ邮箱网页版快速登录 QQ邮箱邮箱账号官方入口地址
J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明
Angular中父组件异步更新子组件复选框状态的实践指南
微信网页版官方快速登录入口 微信网页版网页版账号直达
解决深度学习模型训练初期异常高损失与完美验证准确率问题
如何在J*a中使用Locale处理多语言环境
如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程


2025-11-11
浏览次数:次
返回列表
g>
<strong>}</strong>
<strong>for (auto& shape : shapes) {</strong>
<strong>shape->accept(areaVisitor);</strong>
<strong>}</strong>
<strong>std::cout << "总面积: " << areaVisitor.totalArea << "\n";</strong>
<strong>return 0;</strong>