千家信息网

C++如何实现访问者模式

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,这篇文章将为大家详细讲解有关C++如何实现访问者模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、访问者模式基础知识1.1 模式动机对于系统中的某些对象中可能存
千家信息网最后更新 2025年01月19日C++如何实现访问者模式

这篇文章将为大家详细讲解有关C++如何实现访问者模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、访问者模式基础知识

1.1 模式动机

对于系统中的某些对象中可能存在多种不同类型的元素,而且不同的调用者使用这些元素时也有所区别,这些调用者称为访问者。

访问者模式(Visitor Pattern):表示一个作用于某对象结构中各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

访问者模式的应用场景:

  • 访问者模式适用于数据结构相对稳定的系统

  • 它把数据结构和作用于数据结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

  • 访问者模式的目的是要把处理从数据结构分离出来。如果这样的系统有比较稳定的数据结构,又有已与变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得更容易。反之亦然。

1.2 访问者模式结构

访问者模式中对象结构存储了不同类型的元素对象,以提供不同访问者访问。访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。

相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同的方式访问。

(1)Visitor (抽象访问者)

抽象访问者为对象结构类中每一个具体元素类声明一个访问操作。

(2)ConcreteVisitor (具体访问者)

具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种元素类型的元素。

(3)Element(抽象元素)

抽象元素一般是抽象类或接口,定义一个accept()方法,该方法以一个抽象访问者作为参数。

(4)ConcreteElement (具体元素)

具体访问者实现了accept()方法,在其accept()

(5)ObjectStructure(对象结构)

对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。

1.3 访问者模式优缺点

访问者模式优点:

  • 访问者模式的优点就是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。

模式的缺点:

  • 使增加新的元素类变得困难。在访问者模式中,每增加一个新的元素都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者中增加相应的具体操作,违背"开闭原则"的要求。

1.4 访问者模式应用

#include  #include  using namespace std; class ConcreteElementA;class ConcreteElementB; /*抽象访问者  声明了访问元素对象的方法,通常为每一种类型的元素对象都提供一个访问方法*/class Visitor { public:      virtual void VisitConcreteElementA(ConcreteElementA *pElementA) = 0;     virtual void VisitConcreteElementB(ConcreteElementB *pElementB) = 0; }; /*具体访问者 用于定义对不同类型元素对象的操作*/class ConcreteVisitor1 : public Visitor {public:     void VisitConcreteElementA(ConcreteElementA *pElementA){        // 现在根据传进来的pElementA,可以对ConcreteElementA中的element进行操作    }      void VisitConcreteElementB(ConcreteElementB *pElementB){         // 现在根据传进来的pElementB,可以对ConcreteElementB中的element进行操作    } }; /*具体访问者2*/class ConcreteVisitor2 : public Visitor{ public:     void VisitConcreteElementA(ConcreteElementA *pElementA){    }     void VisitConcreteElementB(ConcreteElementB *pElementB){    }};  /*抽象元素类 声明accept()方法,用于接受访问者的访问*/class Element {public:     virtual void Accept(Visitor *pVisitor) = 0;//accept用于接受访问者的访问}; /*具体元素类 通过调用Visitor类的visit()方法实现对元素的访问*/class ConcreteElementA : public Element{public:     void Accept(Visitor *pVisitor)//通过调用visitor对象的 visit()方法实现对元素对象的访问    {        pVisitor->VisitConcreteElementA(this);    }}; /*具体元素类 */class ConcreteElementB : public Element{public:     void Accept(Visitor *pVisitor)    {     pVisitor->VisitConcreteElementB(this);    }}; // ObjectStructure类(对象结构类),能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素class ObjectStructure{public:     void Attach(Element *pElement){         elements.push_back(pElement);    }      void Detach(Element *pElement)       {          vector::iterator it = find(elements.begin(), elements.end(), pElement);         if (it != elements.end())         {              elements.erase(it);         }    }      void Accept(Visitor *pVisitor){     // 为每一个element设置visitor,进行对应的操作         for (vector::const_iterator it = elements.begin(); it != elements.end(); ++it)         {              (*it)->Accept(pVisitor);         } } int main(){     //实例化对象结构,用于存放元素对象,提供遍历其内部元素的方法     ObjectStructure *pObject = new ObjectStructure;      //实例化具体元素 并将创建好的元素放入对象结构中     ConcreteElementA *pElementA = new ConcreteElementA;     ConcreteElementB *pElementB = new ConcreteElementB;     pObject->Attach(pElementA);     pObject->Attach(pElementB);     //实例化访问者                                                                                                                           ConcreteVisitor1 *pVisitor1 = new ConcreteVisitor1;     ConcreteVisitor2 *pVisitor2 = new ConcreteVisitor2;     //调用accept方法 来接受访问者对象的访问     pObject->Accept(pVisitor1);     pObject->Accept(pVisitor2);      if (pVisitor2) delete pVisitor2;     if (pVisitor1) delete pVisitor1;     if (pElementB) delete pElementB;     if (pElementA) delete pElementA;     if (pObject) delete pObject;      return 0;}

关于"C++如何实现访问者模式"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0