首页 > 后端开发 > C++ > 正文

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

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

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

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

访问者模式的核心思想

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

关键角色包括:

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

基本实现步骤

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

立即学习C++免费学习笔记(深入)”;

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,反向调用访问者对应方法:

蚂蚁PPT
蚂蚁PPT

AI在线智能生成PPT

蚂蚁PPT 113
查看详情 蚂蚁PPT
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;"><pre class="brush:php;toolbar:false;">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 << "Saving circle data: radius=" << circle->radius() << "\n"; }

void visitRectangle(const Rectangle* rectangle) override {
    std::cout << "Saving 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;
SaveVisitor saveVisitor;</p><p>for (const auto& shape : shapes) {
shape->accept(drawVisitor);   // 执行绘制
}</p><p>for (const auto& shape : shapes) {
shape->accept(saveVisitor);   // 执行保存
}
登录后复制

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

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

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

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号