当前位置: 首页 > news >正文

滨海新区做网站电话搜索引擎营销的特点包括

滨海新区做网站电话,搜索引擎营销的特点包括,有什么手机做网站的,杭州设计公司老板被点火1 访问者模式的基本概念 C中的访问者模式是一种行为设计模式,它允许你在不修改类层次结构的情况下增加新的操作。这种模式将数据结构与数据操作解耦,使得操作可以独立于对象的类来定义。 访问者模式的主要组成部分包括: (1&…

1 访问者模式的基本概念

C++中的访问者模式是一种行为设计模式,它允许你在不修改类层次结构的情况下增加新的操作。这种模式将数据结构与数据操作解耦,使得操作可以独立于对象的类来定义。

访问者模式的主要组成部分包括:

(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_ptr<Element>& element) const = 0;
};// 步骤二:定义元素接口  
class Element : public std::enable_shared_from_this<Element> {
public:virtual ~Element() = default;virtual void accept(const std::shared_ptr<Visitor>& visitor) = 0;
};// 步骤三:实现具体元素类  
class ConcreteElement : public Element {
public:void accept(const std::shared_ptr<Visitor>& 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_ptr<Element>& element) const override {auto concreteElement = std::dynamic_pointer_cast<ConcreteElement>(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_ptr<Element>& element) {m_elements.push_back(element);}void detach(const std::shared_ptr<Element>& 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_ptr<Visitor>& visitor) const {for (const auto& element : m_elements) {element->accept(visitor);}}private:std::vector<std::shared_ptr<Element>> m_elements;
};// 步骤六:使用访问者模式  
int main() 
{// 创建对象结构并添加元素  ObjectStructure objectStructure;objectStructure.attach(std::make_shared<ConcreteElement>());// 创建访问者  std::shared_ptr<Visitor> visitor = std::make_shared<ConcreteVisitor>();// 执行访问  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_ptr<Character>& character) const = 0;
};// 元素接口  
class Character : public std::enable_shared_from_this<Character> {
public:virtual ~Character() = default;virtual void accept(const std::shared_ptr<Visitor>& 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_ptr<Visitor>& 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_ptr<Visitor>& 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_ptr<Character>& character) const override {std::cout << "Rendering " << character->getName() << std::endl;}
};// 具体访问者类:AI处理器  
class AIProcessor : public Visitor {
public:void visit(const std::shared_ptr<Character>& character) const override {std::cout << "Processing AI for " << character->getName() << std::endl;// 这里可以根据角色类型执行不同的AI逻辑  }
};

最后,定义一个管理游戏角色的对象结构类,并使用访问者进行双层分派:

// 对象结构类:游戏世界  
class GameWorld {
public:void addCharacter(const std::shared_ptr<Character>& character) {m_characters.push_back(character);}void render(const std::shared_ptr<Visitor>& visitor) const {for (const auto& character : m_characters) {character->accept(visitor);}}private:std::vector<std::shared_ptr<Character>> m_characters;
};int main() 
{// 创建游戏角色  auto warrior = std::make_shared<Warrior>();auto mage = std::make_shared<Mage>();// 创建游戏世界并添加角色  GameWorld gameWorld;gameWorld.addCharacter(warrior);gameWorld.addCharacter(mage);// 创建渲染器访问者  auto renderer = std::make_shared<Renderer>();// 使用渲染器访问者渲染所有角色  gameWorld.render(renderer);// 创建AI处理器访问者  auto aiProcessor = std::make_shared<AIProcessor>();// 使用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_this<Shape> {
public:virtual ~Shape() = default;virtual void accept(const std::shared_ptr<Visitor>& visitor) = 0;
};class Circle;
class Rectangle;// 访问者接口  
class Visitor {
public:virtual ~Visitor() = default;virtual void visit(const std::shared_ptr<Circle>& circle) const = 0;virtual void visit(const std::shared_ptr<Rectangle>& rectangle) const = 0;
};

接着,定义具体的形状类和访问者类:

// 圆形类  
class Circle : public Shape {double radius;
public:Circle(double r) : radius(r) {}void accept(const std::shared_ptr<Visitor>& visitor) override {visitor->visit(std::dynamic_pointer_cast<Circle>(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_ptr<Visitor>& visitor) override {visitor->visit(std::dynamic_pointer_cast<Rectangle>(shared_from_this()));}double getWidth() const { return width; }double getHeight() const { return height; }
};// 计算面积的访问者  
class AreaVisitor : public Visitor {
public:void visit(const std::shared_ptr<Circle>& circle) const override {std::cout << "Circle area: " << 3.14159 * circle->getRadius() * circle->getRadius() << std::endl;}void visit(const std::shared_ptr<Rectangle>& rectangle) const override {std::cout << "Rectangle area: " << rectangle->getWidth() * rectangle->getHeight() << std::endl;}
};// 计算周长的访问者  
class PerimeterVisitor : public Visitor {
public:void visit(const std::shared_ptr<Circle>& circle) const override {std::cout << "Circle perimeter: " << 2 * 3.14159 * circle->getRadius() << std::endl;}void visit(const std::shared_ptr<Rectangle>& rectangle) const override {std::cout << "Rectangle perimeter: " << 2 * (rectangle->getWidth() + rectangle->getHeight()) << std::endl;}
};

最后,创建一个管理形状的对象结构类,并使用访问者进行操作:

// 对象结构类:形状集合  
class ShapeCollection {
public:void addShape(const std::shared_ptr<Shape>& shape) {m_shapes.push_back(shape);}void process(const std::shared_ptr<Visitor>& visitor) const {for (const auto& shape : m_shapes) {shape->accept(visitor);}}private:std::vector<std::shared_ptr<Shape>> m_shapes;
};int main() 
{// 创建形状  auto circle = std::make_shared<Circle>(5.0);auto rectangle = std::make_shared<Rectangle>(4.0, 6.0);// 创建形状集合并添加形状  ShapeCollection collection;collection.addShape(circle);collection.addShape(rectangle);// 创建并使用面积访问者  auto areaVisitor = std::make_shared<AreaVisitor>();collection.process(areaVisitor);// 创建并使用周长访问者  auto perimeterVisitor = std::make_shared<PerimeterVisitor>();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)性能开销: 由于访问者模式涉及到双分派,因此在某些情况下可能会引入额外的性能开销。

http://www.dt0577.cn/news/13677.html

相关文章:

  • 沈阳网站建设哪家便宜兰州seo公司
  • 龙华做网站联系电话短信营销
  • 模拟网站建设快速排名优化
  • 网站建设岗位能力正规考证培训机构
  • 做长海报的网站整站优化网站
  • 虚拟主机和网站空间网站注册地址
  • 做网站图片教程网站推广的方式有哪些?
  • 什么样的网站需要数据库搜索引擎优化seo的英文全称是
  • 手机企业网站源码东莞seo推广公司
  • 山东安康建设项目管理有限公司网站最近几天的新闻
  • php class 做网站南山网站seo
  • 网站建设流程教程seo的实现方式
  • 北京做家教的的网站如何建网站要什么条件
  • 房地产建筑公司网站广告主平台
  • 网站建设技术架构和语言舆情网站直接打开
  • 德清做网站百度代理推广
  • 怡清源在慧聪网网站建设情况专业外贸网络推广
  • 体育论坛网站建设搜索引擎优化论文3000字
  • 网站建设的前期开发国际军事最新消息今天
  • 做恋足的视频网站深圳seo优化排名公司
  • 导航网站建设百度快速提交入口
  • 做家教什么网站seo搜索引擎优化师
  • 网站开发与设计实训心得app营销十大成功案例
  • 游戏模型外包网站google优化排名
  • wordpress怎么看展现量文章优化软件
  • 酒业网站模板下载网页界面设计
  • java能做网站吗seo推广话术
  • 做个动态网站多少钱国际新闻界期刊
  • 湛江公司做网站百度关键词搜索量排行
  • 大理网站制作全国疫情最新报告