IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++实现访问者模式 -> 正文阅读

[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 <iostream>

#include <vector>

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<Element *>::iterator it = find(elements.begin(), elements.end(), pElement);
????     if (it != elements.end())
????     {
?????????     elements.erase(it);
????     }
    }

???? void Accept(Visitor *pVisitor){
???? // 为每一个element设置visitor,进行对应的操作
????     for (vector<Element *>::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;
}

参考文献:

【1】访问者模式(c++实现)访问者模式(c++实现) - 鬼谷子com - 博客园

【2】C++设计模式之访问者模式:?https://www.jb51.net/article/55999.htm

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:48:45  更:2021-09-19 07:50:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 13:52:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计