访问者模式用于分离稳定的数据结构与易变的操作,通过双分派实现开闭原则;核心角色为Visitor(定义visit重载)、Element(实现accept)和ObjectStructure(遍历元素);需注意const正确性与新增类型对Visitor的侵入性。
访问者模式(Visitor Pattern)在 C++ 中主要用于分离数据结构与作用于其上的操作,特别适合当对象结构稳定但操作频繁变化的场景。它通过双分派机制,让新增操作无需修改现有类,符合开闭原则。
Visitor 模式包含三个关键角色:
C++ 不原生支持双分派,访问者模式靠两次虚函数调用模拟:第一次是 Element::accept() 的虚调用(确定元素类型),第二次是 Visitor::visit(ElementType&) 的重载解析(确定操作类型)。需注意:
Visitor 基类:
struct Visitor {
virtual void visit(const Circle&) = 0;
virtual void visit(const Rectangle&) = 0;
virtual ~Visitor() = default;
};
Element 基类及实现:
struct Element {
virtual void accept(Visitor&) const = 0;
virtual ~Element() = default;
};
struct Circle : Element {
double r;
void accept(Visitor& v) const override { v.visit(*this); }
};
struct Rectangle : Element {
double w, h;
void accept(Visitor& v) const override {
v.visit(*this); }
};
具体访问者与使用:
struct PrintVisitor : Visitor {
void visit(const Circle& c) const override { cout << "Circle(r=" << c.r << ")"; }
void visit(const Rectangle& r) const override { cout << "Rect(w=" << r.w << ",h=" << r.h << ")"; }
};
// 使用
vector> shapes = {make_shared(Circle{2.0}), make_shared(Rectangle{3.0,4.0})};
PrintVisitor printer;
for (const auto& e : shapes) e->accept(printer);
适合结构稳定(如 AST、GUI 控件树、几何图元集合)、操作多变(渲染、导出、校验、优化)的情况。但要注意:
基本上就这些。用好访问者,关键在想清楚“谁变谁不变”——结构不变、行为常变时,它很踏实。
# c++
# red
# 命名空间
# 封装
# 多态
# 子类
# const
# void
# 指针
# 数据结构
# 重载函数
# 虚函数
# 接口
# 对象
# this
# 异步
# 遍历
# 需注意
# 这是
# 若需
# 开闭
# 都要
# 也能
# 两次
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
php查询数据怎么分组_groupby分组查询配合聚合函数【技巧】
如何在Golang中捕获HTTP服务器错误_GolangHTTP Handler中error处理
如何在Golang中实现邮件发送功能_Golang SMTP发送与错误处理示例
Win11怎么解压RAR文件 Win11自带解压功能使用方法
Win11怎么开启远程桌面连接_Windows11系统属性远程设置
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
如何用正则与预处理高效拦截带干扰符的恶意域名
微信JSAPI支付回调PHP怎么接收_处理JSAPI异步通知数据方法【指南】
PythonWeb前后端整合项目教程_FastAPIReact完整实例
Win11怎么设置默认视频播放器_Windows 11关联媒体文件打开方式【步骤】
MAC的“接续互通”功能无法使用怎么办_MAC检查蓝牙、Wi-Fi和相同Apple ID登录
Win11怎么设置鼠标宏_Win11鼠标按键自定义编程教程【详解】
Windows11怎么用“记事本”自动换行与编码 Windows11记事本启用自动换行选择UTF-8编码避免乱码兼容多语言【教程】
如何使用Golang进行HTTP服务性能测试_测量吞吐量和延迟
Win11怎么关闭通知中心_Windows11系统通知与专注助手设置
短链接怎么用php递归还原_多层加密链接的处理法【详解】
Windows10系统怎么查看运行时间_Win10 CPU正常运行时间查询
电脑无法识别U盘怎么办 Windows磁盘管理与驱动更新修复识别问题【解决】
PyTorch DDP 多进程训练在 Kaggle 笔记本中的正确启动方式
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
Win10如何设置双wan路由器 Win10双wan路由器设置方法【指南】
Windows如何拦截腾讯视频广告_Windows拦截腾讯视频广告方法【方法】
Linux如何申请SSL免费证书_Linux下Certbot安装与Nginx自动续期【指南】
c++中如何使用虚函数实现多态_c++多态性实现原理
如何使用Golang写入二进制文件_Golang io Write二进制写入示例
Windows10如何彻底关闭自动更新_Win10服务与组策略双重禁用
win11如何清理传递优化文件 Win11为C盘瘦身删除更新缓存【技巧】
Python路径拼接规范_跨平台处理说明【指导】
如何在JavaScript中动态拼接PHP的base_url与JS变量
c++20的std::format怎么用 比printf更安全高效的格式化方法【详解】
如何开启Windows的远程服务器管理工具(RSAT)?(管理服务器)
c# await 一个已经完成的Task会发生什么
Windows 10怎么把任务栏放在屏幕上方_Windows 10解锁任务栏并拖动位置
MAC如何设置网卡MAC地址克隆_MAC终端修改物理地址与环境模拟【教程】
Win11怎么设置默认输入法 Win11固定中文输入法【步骤】
XSLT怎么生成动态的HTML属性名和标签名
win11 OneDrive怎么彻底关闭 Win11禁用并卸载OneDrive教程【分享】
Windows服务启动类型恢复方法_错误修改导致的系统服务异常
LINUX的SELinux是什么_详解LINUX强制访问控制系统的入门与配置
Win10怎么限制单程序CPU占用上限_Win10任务管理器亲和性或第三方工具均衡负载【技巧】
Win10如何更改开机密码_Windows10登录选项更改密码
Win11任务栏怎么调到左边_Win11开始菜单居左设置教程【步骤】
如何使用Golang sync.Map实现并发安全map_避免锁竞争
php在Linux怎么部署_LNMP环境搭建PHP服务的详细指南【指南】
Python生成器表达式内存优化_惰性计算说明【指导】
Linux怎么查找死循环进程_Linux系统负载分析与进程彻底结束【教程】
C++如何编写函数模板?(泛型编程入门)
零基础学会Python自动化办公_高效处理Excel与PDF文档
Win11无法识别耳机怎么办_解决Win11插耳机没声音问题【步骤】
php485返回数据不完整怎么办_php485数据分包重组处理方法【教程】
2025-12-26
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。