python开发手机网站开发网站后台psd
- 作者: 多梦笔记
- 时间: 2026年02月17日 20:55
当前位置: 首页 > news >正文
python开发手机网站开发,网站后台psd,帝国cms使用手册,seo站长工具平台1 访问者模式的基本概念
C中的访问者模式是一种行为设计模式#xff0c;它允许你在不修改类层次结构的情况下增加新的操作。这种模式将数据结构与数据操作解耦#xff0c;使得操作可以独立于对象的类来定义。
访问者模式的主要组成部分包括#xff1a;
#xff08;1中的访问者模式是一种行为设计模式它允许你在不修改类层次结构的情况下增加新的操作。这种模式将数据结构与数据操作解耦使得操作可以独立于对象的类来定义。
访问者模式的主要组成部分包括
1访问者Visitor 这是一个接口它声明了一个访问操作该操作可以被应用到所有的元素上。访问操作的具体实现在访问者的子类中完成。
2元素Element 这是一个接口它定义了一个接受操作该操作可以被一个访问者访问。元素接口通常有一个接受访问者作为参数的接受方法。
3具体元素Concrete Element 这是实现元素接口的具体类它实现了接受方法该方法将调用访问者的访问方法。
4对象结构Object Structure 这是元素的集合它以一种合适的方式包含元素。对象结构可以是一个简单的集合也可以是一个复杂的树形结构。
2 访问者模式的实现步骤
访问者模式的实现步骤如下
1定义访问者接口
首先需要定义一个访问者接口这个接口声明了所有可能应用于元素对象的操作。这些操作通常作为纯虚函数存在具体的操作实现将由具体的访问者类来完成。
2定义元素接口
接下来定义一个元素接口这个接口声明了一个接受方法该方法接受一个访问者对象作为参数。元素接口中的接受方法通常是虚函数以便在元素的具体类中实现多态性。
3实现具体元素类
然后创建实现元素接口的具体元素类。这些类将包含数据并实现接受方法该方法将调用访问者的访问方法。
4实现具体的访问者类
接着创建实现访问者接口的具体访问者类。这些类将包含访问元素所需的具体逻辑。当访问者的访问方法被调用时它将针对具体的元素对象执行相应的操作。
5创建对象结构
创建一个对象结构该结构负责管理元素对象的集合。这可以是一个简单的容器如数组或向量也可以是一个更复杂的结构如树或图。
6使用访问者模式
最后在客户端代码中创建具体的访问者对象并通过对象结构访问元素对象。当需要执行某个操作时通过对象结构的遍历方法将具体的访问者对象传递给每个元素对象的接受方法。元素对象的接受方法将调用访问者的访问方法从而执行相应的操作。
如下为样例代码
#include iostream
#include vector
#include memory class Element;// 步骤一定义访问者接口
class Visitor {
public:virtual ~Visitor() default;virtual void visit(const std::shared_ptrElement element) const 0;
};// 步骤二定义元素接口
class Element : public std::enable_shared_from_thisElement {
public:virtual ~Element() default;virtual void accept(const std::shared_ptrVisitor visitor) 0;
};// 步骤三实现具体元素类
class ConcreteElement : public Element {
public:void accept(const std::shared_ptrVisitor visitor) override {visitor-visit(shared_from_this());}void operation() const {std::cout ConcreteElement operation std::endl;}
};// 步骤四实现具体的访问者类
class ConcreteVisitor : public Visitor {
public:void visit(const std::shared_ptrElement element) const override {auto concreteElement std::dynamic_pointer_castConcreteElement(element);if (concreteElement) {concreteElement-operation();std::cout Visited by ConcreteVisitor std::endl;}else {std::cout Element is not of type ConcreteElement std::endl;}}
};// 步骤五创建对象结构
class ObjectStructure {
public:void attach(const std::shared_ptrElement element) {m_elements.push_back(element);}void detach(const std::shared_ptrElement element) {auto it std::find(m_elements.begin(), m_elements.end(), element);if (it ! m_elements.end()) {m_elements.erase(it);}}void accept(const std::shared_ptrVisitor visitor) const {for (const auto element : m_elements) {element-accept(visitor);}}private:std::vectorstd::shared_ptrElement m_elements;
};// 步骤六使用访问者模式
int main()
{// 创建对象结构并添加元素 ObjectStructure objectStructure;objectStructure.attach(std::make_sharedConcreteElement());// 创建访问者 std::shared_ptrVisitor visitor std::make_sharedConcreteVisitor();// 执行访问 objectStructure.accept(visitor);return 0;
}上面代码的输出为
ConcreteElement operation
Visited by ConcreteVisitor上面的代码使用了 std::shared_ptr 智能指针来管理 Visitor 和 Element 对象的生命周期。std::dynamic_pointer_cast 用于安全地执行动态类型转换以确认 Element 指针是否可以转换为 ConcreteElement 类型。如果转换成功则执行相应的操作。
ObjectStructure 类负责管理 Element 对象的集合并提供 attach 和 detach 方法来添加和删除元素。accept 方法则遍历所有元素并将访问者传递给每个元素的 accept 方法从而执行访问操作。
在 main 函数中创建了一个 ObjectStructure 对象并向其添加了一个 ConcreteElement 对象。然后创建了一个 ConcreteVisitor 对象并通过 ObjectStructure 的 accept 方法将访问者传递给所有元素。这样就实现了访问者模式的使用。
3 访问者模式的应用场景
C 访问者模式的应用场景广泛主要适用于以下情况
1双层分派场景 访问者模式实现了一种称为“双层分派”的机制。第一层分派发生在客户端代码中当客户端将访问者对象传递给元素对象的 accept 方法时。第二层分派发生在元素对象的 accept 方法内部它根据访问者的类型调用相应的访问方法。这种双层分派机制使得操作可以在元素对象的上下文中执行并且可以根据元素的类型进行不同的处理。
2数据结构稳定但操作易变的场景 如果数据结构相对稳定但需要在其上执行的操作经常变化访问者模式可以帮助将这些操作与数据结构解耦使得操作的变化不会影响到数据结构的定义。
3操作需要扩展的场景 当需要对一个对象结构中的元素执行多种不同的、不相关的操作时且这些操作可能会在未来发生变化或增加时使用访问者模式非常合适。通过将操作封装在访问者中可以在不修改元素类的情况下添加新的操作。
4需要对对象结构中的对象进行不同操作的场景 当需要在运行时决定对对象结构中的哪些元素执行哪些操作时访问者模式可以很容易地实现这种动态行为。
5复杂的对象结构遍历 当需要遍历一个复杂的对象结构如树形结构、图结构等并对结构中的每个元素执行特定的操作时访问者模式可以简化代码结构使得遍历和操作逻辑更加清晰和分离。
3.1 访问者模式应用于双层分派场景
双层分派允许根据对象类型和访问者类型动态地决定执行哪个操作。以下是一个简单的游戏场景其中游戏角色可以被不同的访问者例如渲染器或AI处理器访问。
首先定义访问者接口和元素接口
#include iostream
#include memory
#include vector
#include string class Character;// 访问者接口
class Visitor {
public:virtual ~Visitor() default;virtual void visit(const std::shared_ptrCharacter character) const 0;
};// 元素接口
class Character : public std::enable_shared_from_thisCharacter {
public:virtual ~Character() default;virtual void accept(const std::shared_ptrVisitor visitor) 0;virtual std::string getName() const 0;
};接着定义具体的游戏角色类和访问者类
// 具体游戏角色类A
class Warrior : public Character {
public:std::string getName() const override { return Warrior; }void accept(const std::shared_ptrVisitor visitor) override {visitor-visit(shared_from_this());}void fight() const {std::cout getName() is fighting! std::endl;}
};// 具体游戏角色类B
class Mage : public Character {
public:std::string getName() const override { return Mage; }void accept(const std::shared_ptrVisitor visitor) override {visitor-visit(shared_from_this());}void castSpell() const {std::cout getName() is casting a spell! std::endl;}
};// 具体访问者类渲染器
class Renderer : public Visitor {
public:void visit(const std::shared_ptrCharacter character) const override {std::cout Rendering character-getName() std::endl;}
};// 具体访问者类AI处理器
class AIProcessor : public Visitor {
public:void visit(const std::shared_ptrCharacter character) const override {std::cout Processing AI for character-getName() std::endl;// 这里可以根据角色类型执行不同的AI逻辑 }
};最后定义一个管理游戏角色的对象结构类并使用访问者进行双层分派
// 对象结构类游戏世界
class GameWorld {
public:void addCharacter(const std::shared_ptrCharacter character) {m_characters.push_back(character);}void render(const std::shared_ptrVisitor visitor) const {for (const auto character : m_characters) {character-accept(visitor);}}private:std::vectorstd::shared_ptrCharacter m_characters;
};int main()
{// 创建游戏角色 auto warrior std::make_sharedWarrior();auto mage std::make_sharedMage();// 创建游戏世界并添加角色 GameWorld gameWorld;gameWorld.addCharacter(warrior);gameWorld.addCharacter(mage);// 创建渲染器访问者 auto renderer std::make_sharedRenderer();// 使用渲染器访问者渲染所有角色 gameWorld.render(renderer);// 创建AI处理器访问者 auto aiProcessor std::make_sharedAIProcessor();// 使用AI处理器访问者处理所有角色的AI gameWorld.render(aiProcessor);// 不需要手动释放对象智能指针会自动处理 return 0;
}上面代码的输出为
Rendering Warrior
Rendering Mage
Processing AI for Warrior
Processing AI for Mage在这个示例中Warrior 和 Mage 类继承了 Character 接口并实现了各自的 accept 方法和特定行为如 fight 和 castSpell。Renderer 和 AIProcessor 类继承了 Visitor 接口并实现了针对 Character 的 visit 方法。
GameWorld 类管理着游戏中的角色并提供了 render 方法该方法接受一个 Visitor 智能指针并使用 accept 方法触发双层分派。当调用 gameWorld.render(renderer) 时所有角色都会被渲染器访问并调用它们各自的 accept 方法。由于 accept 方法内部调用了 visitor-visit(shared_from_this())这就会触发对应的 visit 方法在这里是 Renderer 类的 visit 方法负责渲染角色。
3.2 访问者模式应用数据结构稳定但操作易变的场景
该场景是指对于一组稳定的数据结构元素在这些数据结构上执行各种易变的操作访问者时每个操作可能需要访问数据结构的不同部分并且可能以不同的方式处理这些部分。
下面是一个使用访问者模式的示例它模拟了一个简单的形状集合其中形状是稳定的数据结构而不同的操作如计算面积、周长等是易变的访问者。
首先定义形状接口和访问者接口
#include iostream
#include memory
#include vector class Visitor;// 形状接口
class Shape : public std::enable_shared_from_thisShape {
public:virtual ~Shape() default;virtual void accept(const std::shared_ptrVisitor visitor) 0;
};class Circle;
class Rectangle;// 访问者接口
class Visitor {
public:virtual ~Visitor() default;virtual void visit(const std::shared_ptrCircle circle) const 0;virtual void visit(const std::shared_ptrRectangle rectangle) const 0;
};接着定义具体的形状类和访问者类
// 圆形类
class Circle : public Shape {double radius;
public:Circle(double r) : radius® {}void accept(const std::shared_ptrVisitor visitor) override {visitor-visit(std::dynamic_pointer_castCircle(shared_from_this()));}double getRadius() const { return radius; }
};// 矩形类
class Rectangle : public Shape {double width, height;
public:Rectangle(double w, double h) : width(w), height(h) {}void accept(const std::shared_ptrVisitor visitor) override {visitor-visit(std::dynamic_pointer_castRectangle(shared_from_this()));}double getWidth() const { return width; }double getHeight() const { return height; }
};// 计算面积的访问者
class AreaVisitor : public Visitor {
public:void visit(const std::shared_ptrCircle circle) const override {std::cout Circle area: 3.14159 * circle-getRadius() * circle-getRadius() std::endl;}void visit(const std::shared_ptrRectangle rectangle) const override {std::cout Rectangle area: rectangle-getWidth() * rectangle-getHeight() std::endl;}
};// 计算周长的访问者
class PerimeterVisitor : public Visitor {
public:void visit(const std::shared_ptrCircle circle) const override {std::cout Circle perimeter: 2 * 3.14159 * circle-getRadius() std::endl;}void visit(const std::shared_ptrRectangle rectangle) const override {std::cout Rectangle perimeter: 2 * (rectangle-getWidth() rectangle-getHeight()) std::endl;}
};最后创建一个管理形状的对象结构类并使用访问者进行操作
// 对象结构类形状集合
class ShapeCollection {
public:void addShape(const std::shared_ptrShape shape) {m_shapes.push_back(shape);}void process(const std::shared_ptrVisitor visitor) const {for (const auto shape : m_shapes) {shape-accept(visitor);}}private:std::vectorstd::shared_ptrShape m_shapes;
};int main()
{// 创建形状 auto circle std::make_sharedCircle(5.0);auto rectangle std::make_sharedRectangle(4.0, 6.0);// 创建形状集合并添加形状 ShapeCollection collection;collection.addShape(circle);collection.addShape(rectangle);// 创建并使用面积访问者 auto areaVisitor std::make_sharedAreaVisitor();collection.process(areaVisitor);// 创建并使用周长访问者 auto perimeterVisitor std::make_sharedPerimeterVisitor();collection.process(perimeterVisitor);// 不需要手动释放对象智能指针会自动处理 return 0;
}上面代码的输出为
Circle area: 78.5397
Rectangle area: 24
Circle perimeter: 31.4159
Rectangle perimeter: 20在这个示例中Circle 和 Rectangle 类继承了 Shape 接口并实现了各自的 accept 方法和特定行为半径以及长宽。AreaVisitor 和 PerimeterVisitor 类继承了 Visitor 接口并实现了计算圆形面积周长以及计算矩形面积周长的 visit 方法。随后在 ShapeCollection 的 process 进行访问调用。
4 访问者模式的优点与缺点
C 访问者模式的优点主要包括
1扩展性好 访问者模式使得在不修改已有类的情况下可以添加新的操作。这意味着数据结构本身保持稳定而新的操作可以很容易地添加到系统中。
2操作集中管理 访问者模式将相关的操作集中到一个访问者类中这有助于操作的封装和复用。
3双分派 访问者模式通过对象的“接受”方法和访问者的“访问”方法实现了双分派即运行时根据对象的实际类型和访问者的类型来确定执行的操作。
4灵活性 访问者模式允许我们根据需要灵活地定义不同的访问者类实现不同的操作逻辑。
5符合开闭原则 访问者模式符合开闭原则即对扩展开放对修改封闭。当需要添加新的操作时我们只需要添加新的访问者类而不需要修改已有的数据结构。
然而C 访问者模式也存在一些缺点
1增加复杂性 访问者模式增加了类的数量使得系统变得更加复杂。每个元素类都需要实现接受方法每个访问者类都需要实现访问方法这可能导致代码量的增加。
2破坏封装性 访问者模式要求元素类暴露其内部状态给访问者类这可能会破坏元素的封装性。如果访问者类不恰当地使用这些内部状态可能会导致错误或不可预见的行为。
3类型安全 在访问者模式中由于访问者类需要访问元素类的内部状态因此需要确保类型安全。否则可能会导致运行时错误。
4性能开销 由于访问者模式涉及到双分派因此在某些情况下可能会引入额外的性能开销。
相关文章
-
python和php网站开发网站建设开发公司定制网站制作
python和php网站开发网站建设开发公司定制网站制作
- 站长
- 2026年02月17日
-
python大型网站开发电子商务网站建设与管理论文
python大型网站开发电子商务网站建设与管理论文
- 站长
- 2026年02月17日
-
python 做网站很快吗免费模式营销案例
python 做网站很快吗免费模式营销案例
- 站长
- 2026年02月17日
-
python爬虫做网站高新区手机网站建设
python爬虫做网站高新区手机网站建设
- 站长
- 2026年02月17日
-
Python爬取wordpress搜索引擎优化的专家是什么意思
Python爬取wordpress搜索引擎优化的专家是什么意思
- 站长
- 2026年02月17日
-
python网站建设代码网页制作基础教程26页简答题是什么
python网站建设代码网页制作基础教程26页简答题是什么
- 站长
- 2026年02月17日
