首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用C++模板实现访问者模式

访问者模式(Visitor Pattern)是一种行为型设计模式,它的目的是在不修改数据结构的情况下,增加新的操作。它通过将操作与数据结构分离,使得我们可以在不修改原有数据结构的基础上,增加新的操作。

访问者模式中包含两个主要的角色:访问者(Visitor)和元素(Element)。访问者负责具体的操作,而元素则是被访问的数据结构。访问者模式中的操作通常是以多态的方式实现的,这样可以让我们在不修改原有代码的情况下,增加新的操作。

在C++中,我们可以使用模板来实现访问者模式。具体来说,我们可以定义一个访问者类,该类包含一个模板函数,该函数接受一个元素类型作为参数,并对该元素类型进行操作。然后,我们可以为每个具体的元素类型实现该模板函数,以实现该元素类型的具体操作。

以下是一个简单的C++访问者模式示例:

代码语言:cpp
复制
#include<iostream>
#include<vector>

// 访问者类
class Visitor {
public:
    template<typename T>
    void visit(T& element) {
        std::cout << "Visiting "<< element.getName()<< std::endl;
    }
};

// 元素类
class Element {
public:
    Element(const std::string& name) : m_name(name) {}
    virtual ~Element() {}

    std::string getName() const {
        return m_name;
    }

private:
    std::string m_name;
};

// 具体元素类A
class ConcreteElementA : public Element {
public:
    ConcreteElementA(const std::string& name) : Element(name) {}

    void accept(Visitor& visitor) {
        visitor.visit(*this);
    }
};

// 具体元素类B
class ConcreteElementB : public Element {
public:
    ConcreteElementB(const std::string& name) : Element(name) {}

    void accept(Visitor& visitor) {
        visitor.visit(*this);
    }
};

int main() {
    std::vector<Element*> elements;
    elements.push_back(new ConcreteElementA("ElementA"));
    elements.push_back(new ConcreteElementB("ElementB"));

    Visitor visitor;
    for (auto& element : elements) {
        element->accept(visitor);
    }

    for (auto& element : elements) {
        delete element;
    }

    return 0;
}

在上述示例中,我们定义了一个访问者类Visitor和一个元素类Element。具体元素类A和具体元素类B都继承自元素类Element,并实现了accept()函数,该函数接受一个访问者类Visitor作为参数,并调用访问者类Visitor的visit()函数来实现具体的操作。

在main()函数中,我们创建了一个访问者类Visitor和一些具体元素类的实例,并将这些实例添加到一个vector容器中。然后,我们遍历该容器,对每个元素调用accept()函数来实现具体的操作。

需要注意的是,在上述示例中,我们使用了模板来实现访问者模式。具体来说,我们在访问者类Visitor中定义了一个模板函数visit(),该函数接受一个元素类型作为参数,并对该元素类型进行操作。然后,我们为每个具体的元素类型实现该模板函数,以实现该元素类型的具体操作。这样可以让我们在不修改原有代码的情况下,增加新的操作。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

行为型之访问者模式C++实现

可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。 灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。...在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。 破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。...访问者模式依赖了具体类,而没有依赖抽象类 主要角色: 抽象访问者:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素。...具体访问者实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。...对象结构:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现

18610

C++设计模式 - 访问者模式

注: 在最初的访问者模式类图没有管理类的角色,这里为了方便客户端使用接口,才增加此类。实际场景中,只要运用到访问者模式思想即可,没有必要参照其实现方式生搬硬套。...,在CComputePartBase的Accept()接口的实现中会被使用到。...CSafeMgr只是为了方便客户端使用配件类和访问者类。实际访问者模式的设计中没有此角色,可参考「意义」上的类图。...为了解决各个模块头文件相互引用问题,这里多次使用C++的前置声明。是一种解决这类问题比较实用的方法。 每增加一个行为要增加多个类,加入这些功能是不需要的,清理起来也是比较复杂的。...因此在使用访问者模式前,先审视是否有必要。 访问者模式实现相对来说很复杂,因为涉及到各个类的双向交互。同时领略访问者的思想,选择恰当的实现方式即可。

31720

C++设计模式 - 模板方法模式

模板方法 ❝模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。...❞ 模板方法模式利用C++多态特征,在父类定义一套结构流程,其中通用部分在父类实现,子类继承父类实现差异性的接口。...意义 模板方法模式是比较实用的一种设计模式,将不变部分的流程和接口在父类实现,变化部分的接口预留出来交由子类实现。如此,有利于代码的复用性、可扩展性。 应用场景 一位头痛和一位胃疼的病人去医院看病。...总结 当希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时, 可使用模板方法模式。...模板方法将整个算法转换为一系列独立的步骤, 以便子类能对其进行扩展, 同时还可让超类中所定义的结构保持完整。 当多个类的算法除一些细微不同之外几乎完全一样时, 可使用模式

39930

c++模板使用

template 类模板,类模板成员实现在头文件中 template class MyPair{ T value[2]; }; 函数模板 template <typename...a : b; } 模板特例化 模板特例化和模板重载函数可以共存,编译期针对不同的数据类型,生成多个版本的函数,c++11之后可以使用constexpr常量表达式,写编译期代码 template class...T> int Size(S a, T... b){ return Size(b...)+1; } int ii = Size(1,2,4,5); //size= 4 模板作为参数 类模板参数...template class Thing> class Crab{} Crab a;//使用模板作为类模板 函数模板参数 template...T的对象值 if constexpr () 编译期的条件判断,根据constexpr内部生成多条代码 模板执行在编译器,所以模板成员只要传入的参数匹配,写固定的成员变量,只要编译过了也是可以的

72820

C++设计模式——Template Method模板方法模式

一,模板方法模式的定义 模板方法模式是一种行为型设计模式,它先定义了一个算法的大致框架,然后将算法的具体实现步骤分解到多个子类中。...模板方法模式为算法设计了一个抽象的模板,算法的具体代码细节由子类来实现,从而使算法在整体上结构稳定,但是又能被灵活修改和扩展。...二,模板方法模式的结构 模板方法模式主要包含以下组件: 1.抽象类(AbstractClass): 定了算法的大致框架,里面包含了一个模板方法(templateMethod)和多个基本操作方法(execute1...五,模板方法模式的优缺点 模板方法模式的优点: 使代码更加简洁,具体细节交给子类实现,避免了重复代码。 模板方法定义以后,后面只需要重点维护子类的代码实现,系统可扩展性和灵活性很强。...六,代码实战 基于模板方法模式实现的模拟汽车生产 #include class VehicleTemplate { public: void buildVehicle()

8310

访问者模式在 Kubernetes 中的使用

访问者模式被认为是最复杂的设计模式,并且使用频率不高,《设计模式》的作者评价为:大多情况下,你不需要使用访问者模式,但是一旦需要使用它时,那就真的需要使用了。...访问者模式 下图很好地展示了访问者模式编码的工作流程。 在 Gof 中,也有关于为什么引入访问者模式的解释。 访问者模式在设计跨类层级结构的异构对象集合的操作时非常有用。...K8s 中的访问者模式 Kubernetes 是一个容器编排平台,上面有各种不同的资源,而 kubectl 是一个命令行工具,它使用以下命令格式来操作资源。...关于这部分代码,大概有700多行,它使用建造者模式(builder.go[4])和访问者模式连接访问者,并通过调用各自的 VisitorFunc[5] 方法来实现对应的功能,同时在 builder.go...当然我们可以直接使用最简单的 Bash 来实现,但是如果增加更多的资源,那么慢慢就会变得难以维护和扩展了,所以我决定使用 Go 来实现它。

2.5K20

学以致用C++设计模式模板方法模式

模板方法模式定义 定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 所以,如果要改算法,那就重构吧。...用武之地 模板方法的有点 封装不变部分,拓展可变部分(把认为是不变部分的算法封装到父类实现,而可变部分可以通过继承来继续拓展。...行为由父类控制,子类实现模板方法的缺点 子类对父类产生了影响,这会加大代码的理解难度,对新手不太友好。 使用场景 多个子类有共同的方法,并且逻辑基本相同。...重要、复杂的算法,可以把核心算法设计为模板方法,周边细节由各个子类实现。 重构时,模板方法模式是一个常见的模式模板方法模式的拓展 可以自己去试试写一个,造车的模板。...对,和模板方法模式相似度挺高的“建造者模式”!

30820

【Go实现】实践GoF的23种设计模式访问者模式

这种场景,使用访问者模式正合适。...与迭代器模式结合 访问者模式经常与迭代器模式一起使用。...编译器中,通常使用访问者模式实现对语法树解析,比如 LLVM。 希望对一个复杂的数据结构执行某些操作,并支持后续扩展。 优缺点 优点 数据结构和操作算法解耦,符合 单一职责原则。...缺点 访问者模式某种程度上,要求数据结构必须对外暴露其内在实现,否则访问者就无法遍历其中数据(可以结合迭代器模式来解决该问题)。 如果被访问对象内的数据结构变更,可能要更新所有的访问者实现。...与其他模式的关联 访问者模式 经常和 迭代器模式 一起使用,使得被访问对象无须向外暴露内在数据结构。 也经常和 组合模式 一起使用,比如在语法树解析中,递归访问和解析树的每个节点(节点组合成树)。

22320

C++跟你聊聊“模板方法模式

可能有的小伙伴会觉得和前面讲过的策略模式有一定的契合度,是有一定的契合度啊,不过“策略模式”的子类自由度更高,而“模板方法模式”的子类自由度相对比较低一些。模板嘛,写死的;策略嘛,调度的。...模板方法模式:定义一个操作中的算法的骨架,而将一些操作延迟到子类中,模板方法使得子类可以在不改变一个算法的结构而重定义该算法的某些特定步骤。...简易选择题判题系统实现 #include using namespace std; class exam { protected: //一些抽象行为,下放到子类实现 virtual...模板方法就是通过吧不变的行为搬到抽象类中,去除子类中的重复代码,来体现它的优势。...模板方法模式提供了一个很好的代码复用平台。

25220

C++使用函数模板

大家好,又见面了,我是全栈君 函数模板: 函数模板是蓝图或处方功能,编译器使用其发电功能系列中的新成员。 第一次使用时,新的功能是创建。从功能模板生成的函数的实例称为模板模板的实例。...函数模板的开始是keywordtemplate,表示这是一个模板。 其后是一对尖括号,它包括了參数列表。 在使用模板中生成的函数之前,必须确保把声明(即原型)或模板的定义放在源文件里。...使用时须要注意两个问题: 第一,函数模板本身不做不论什么工作,它是编译器用于从函数调用中创建函数定义的处方或蓝图。 第二。全部工作都在编译和链接过程中完毕。 编译器使用模板生成函数定义的源码。...此时能够使用该技巧帮助编译器去除不确定性。 2、在一些情况下,编译器不能判断出模板參数,因此无法选择要使用哪个版本号的函数。 3、为了避免有太多的函数版本号(从而避免过多占用内存)。...能够强迫函数调用使用某个版本号的函数。 模板的说明: 对于某个參数值(在有多个參数的模板中,就是一组參数值)。模板的说明定义了它不同于标准模板的动作。模板说明的定义必须放在原语句的声明或定义之后。

38410

从零开始学C++模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象

一、用模板实现单例模式 在前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现: 为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -...即 将Singleton 实现模板类,将ApplicationImpl 类包装成单例模式类,可以看到构造函数和析构函数都只调用了一次。...程序使用一个小技巧,用axexit 函数注册了程序结束时需要调用的函数。...二、模板方式实现动态创建对象 在前面的文章曾经使用宏定义的方式实现动态创建对象,现在在 DynBase.h 中用模板类将宏定义替换掉,其他代码不变: //class Register //{ //public...参考: C++ primer 第四版 Effective C++ 3rd C++编程规范

1.8K00

设计模式学习笔记(二十一)访问者模式及其实现

这就是访问者模式的典型应用场景。 一、访问者模式介绍 1.1 访问者模式的结构 访问者模式是一种较为复杂的行为型模式,它包含访问者(Visitor)和被访问元素(Element)两个主要组成部分。...下面就来看看访问者模式的具体结构: Visitor:抽象访问者,为对象结构中的每个具体元素类声明一个访问操作 ConcreteVisitor1、ConcreteVisitor2:具体访问者实现抽象访问者声明的操作...Client:客户端 1.2 访问者模式实现 根据上面的类图,首先是抽象访问者,为每一种具体类型对象都会提供一个访问方法: public interface Visitor { void visit...在下面的情况可以考虑使用访问者模式: 一个对象结构中包含多个类型的对象,希望对这些对象实施一些依赖其具体类型的操作 需要对一个对象结构中的对象进行很多不同的并且不相关的操作 对象结构中对象对应的类很少改变...家⻓更关⼼孩⼦的成绩和⽼师的能⼒,校⻓更关⼼⽼师所在班级学⽣的⼈数和升学 率 从前面第一节的结构图和实现代码就可以知道,访问者模式的整体类结构相对复杂,下面就来看看该案例的核心逻辑实现: 需要建立用户抽象类和抽象访问方法

22260

C++函数模板与分离编译模式

代码编译运行环境:VS2017+Debug+Win32 ---- 1.分离编译模式 一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件连接起来形成单一的可执行文件的过程称为分离编译模式...2.使用函数模板在链接时出错 在C++程序设计中,在一个源文件中定义某个函数,然后在另一个源文件中使用该函数,这是一种非常普遍的做法。...(1)函数模板的定义写进了头文件,暴露了函数模板实现细节。 (2)不符合分离编译模式的规则,因为分离编译模式要求函数原型申明放在头文件,定义放在源文件。...在不发生函数调用的时候将函数模板实例化,或者在不使用模板的时候将类模板实例化称之为模板显示实例化。...当类模板的成员函数的实现定义在源文件中,通过模板类的对象调用成员函数时也会出现找不到函数定义的错误,可以使用同样的方法解决,不再赘述。

2.9K51

C++】设计模式:观察者、策略、模板

观察者模式 观察者模式的基本原理,通过观察者模式可以实现对象之间的松耦合,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并作出相应的响应。...策略模式 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。定义一系列算法,把它们封装起来,并且使它们可以互相替换。策略模式可以使算法独立于使用它的客户端而变化。...模板方法 模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。...a->templateMethod(); b->templateMethod(); delete a; delete b; return 0; } 通过模板方法模式...,我们可以在父类中定义一个算法的骨架,而将具体实现延迟到子类中,从而实现代码复用和扩展。

6310

使用C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

初识模板方法模式 image.png 上面的需求种, prepareRecipe() 就是模板方法....算法分布在了不同的类里面 使用模板方法后: CaffeineBeverage这个父类控制并保护算法 父类最大化的代码的复用 算法只在一个地方, 改变算法也只需改变这个地方 新的饮料只需实现部分工序即可...三种模式比较: 模板方法模式: 子类决定如何实现算法中特定的步骤 策略模式: 封装变化的行为并使用委托来决定哪个行为被使用. 工厂方法模式: 子类决定实例化哪个具体的类....使用模板方法做排序 看看java里面数组的排序方法: mergeSort就可以看做事模板方法, compareTo()就是需要具体实现的方法....总结 好莱坞原则: "别给我们打电话, 我们给你打电话" 模板方法模式模板方法在一个方法里定义了一套算法的骨架, 算法的某些步骤可以让子类来实现.

59520

行为型之模板方法C++实现

,它可能是存款、取款或者转账等,可以延迟到子类中实现。...模板方法:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 优势: 封装了不变部分,扩展可变部分。...缺点: 对每个不同的实现都需要定义一个子类,会导致类的个数增加。 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。...主要角色: (1)抽象父类: 抽象方法:在抽象类中申明,由具体子类实现。 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。...钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。 (2)具体子类:实现抽象类中所定义的抽象方法和钩子方法。

19820

使用 C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

初识模板方法模式 上面的需求种, prepareRecipe() 就是模板方法. 因为, 它首先是一个方法, 然后它还充当了算法模板的角色, 这个需求里, 算法就是制作饮料的整个工序....算法分布在了不同的类里面 使用模板方法后: CaffeineBeverage这个父类控制并保护算法 父类最大化的代码的复用 算法只在一个地方, 改变算法也只需改变这个地方 新的饮料只需实现部分工序即可...三种模式比较: 模板方法模式: 子类决定如何实现算法中特定的步骤 策略模式: 封装变化的行为并使用委托来决定哪个行为被使用. 工厂方法模式: 子类决定实例化哪个具体的类....使用模板方法做排序 看看java里面数组的排序方法: mergeSort就可以看做事模板方法, compareTo()就是需要具体实现的方法....总结 好莱坞原则: "别给我们打电话, 我们给你打电话" 模板方法模式模板方法在一个方法里定义了一套算法的骨架, 算法的某些步骤可以让子类来实现.

96640
领券