访问者模式通过双重分发在不修改元素类的情况下添加新操作,由Element、ConcreteElement、Visitor、ConcreteVisitor和ObjectStructure组成,适用于数据结构稳定而操作多变的场景。

访问者模式(Visitor Pattern)是一种行为设计模式,它允许你在不修改对象结构的前提下,为对象结构中的元素添加新的操作。C++中实现访问者模式的关键是“双重分发”——通过虚函数实现动态绑定,把操作从数据结构中解耦出来。
访问者模式的核心组成
访问者模式包含以下几个关键角色:
Element(元素):定义一个接受访问者的接口,比如 accept(Visitor&)。ConcreteElement:具体元素类,实现 accept 方法,将调用转发给访问者的 visit 方法。Visitor(访问者):定义对每种元素的访问方法,如 visit(ConcreteElementA&)。ConcreteVisitor:具体访问者,实现各种 visit 方法,封装具体操作。ObjectStructure:能枚举元素并让访问者遍历它们的结构(比如容器)。
基本实现代码示例
下面是一个简单的 C++ 实现,展示如何使用访问者模式处理不同类型的文档元素(文本和图片):
#include #include #include // 前向声明class TextElement;class ImageElement;// 访问者接口class Visitor {public: virtual ~Visitor() = default; virtual void visit(TextElement& element) = 0; virtual void visit(ImageElement& element) = 0;};// 元素基类class Element {public: virtual ~Element() = default; virtual void accept(Visitor& visitor) = 0;};// 具体元素:文本class TextElement : public Element {public: void accept(Visitor& visitor) override { visitor.visit(*this); } std::string getText() const { return "This is a text block."; }};// 具体元素:图片class ImageElement : public Element {public: void accept(Visitor& visitor) override { visitor.visit(*this); } std::string getImageInfo() const { return "Image: photo.jpg, size 1920x1080"; }};// 具体访问者:打印访问者class PrintVisitor : public Visitor {public: void visit(TextElement& element) override { std::cout << "[Print] " << element.getText() << "n"; } void visit(ImageElement& element) override { std::cout << "[Print] " << element.getImageInfo() << "n"; }};// 具体访问者:导出为 HTMLclass HtmlExportVisitor : public Visitor {public: void visit(TextElement& element) override { std::cout << "" << element.getText() << "
立即学习“C++免费学习笔记(深入)”;
n"; } void visit(ImageElement& element) override { std::cout << "@@##@@n"; // 简化提取文件名 }};// 文档结构(对象结构)class Document {private: std::vector<std::unique_ptr> elements;public: void addElement(std::unique_ptr element) { elements.push_back(std::move(element)); } void accept(Visitor& visitor) { for (auto& e : elements) { e->accept(visitor); } }};
使用方式
你可以轻松地添加新操作而无需改动元素类:
int main() { Document doc; doc.addElement(std::make_unique()); doc.addElement(std::make_unique()); PrintVisitor printVisitor; HtmlExportVisitor htmlVisitor; std::cout << "=== 打印文档 ===n"; doc.accept(printVisitor); std::cout << "n=== 导出为 HTML ===n"; doc.accept(htmlVisitor); return 0;}
输出结果:
=== 打印文档 ===[Print] This is a text block.[Print] Image: photo.jpg, size 1920x1080=== 导出为 HTML ===
This is a text block.
@@##@@
访问者模式的优缺点
优点:
新增操作非常方便,只需添加新的访问者类。符合开闭原则:对扩展开放,对修改关闭。集中相关操作,避免污染元素类。
缺点:
如果元素类型频繁变化,每个访问者都要修改,违背开闭原则。代码可读性降低,尤其是初学者不易理解双重分发机制。C++ 中需要前向声明和多重指针管理,稍显繁琐。
基本上就这些。访问者模式适合数据结构稳定但操作多变的场景,比如编译器 AST 处理、文档渲染、序列化等。用好它,能让系统更灵活。
<img src="%22%20<<%20element.getImageInfo().substr(7,%2010)%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20<
以上就是C++怎么实现一个访问者模式(Visitor)_C++设计模式与访问者模式实现的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1485148.html
微信扫一扫
支付宝扫一扫