设计模式的 C++ 实现---访问者模式

前文回顾
单例模式(一)
单例模式(二)
观察者模式
简单工厂模式
工厂方法模式(一)
工厂方法模式(二)
抽象工厂模式(一)
抽象工厂模式(二)
原型模式
外观模式
中介者模式
代理模式
装饰者模式
策略模式
状态模式
命令模式
建造者模式
桥接模式
解释器模式

前言

访问者模式的本质就是想给一系列对象添加新的方法,但是又不想在原来类代码中进行增加,即保持既有的类不变,把要添加的方法再新的类中进行实现。
所谓访问者就是一系列行为的统称,通过多态实现多种行为的添加,通过函数重载实现针对不同对象的特定行为的调用。

实现举例

  1. 场景描述
    假设动物园中只有狗和猫两种动物,开始所有动物只有一个名称属性,但预留了访问者接口,后续可以给动物增加新的行为而不用修改既有的类。
  2. 动物基类
#include <string>
using namespace std;

class Visitor;
class Animal
{
public:
    Animal(const string &m_name):name(m_name){}
    string getName() const {return  name ;}
    virtual ~Animal(){}
    virtual void accept(Visitor *m_visitor) = 0;
protected:
    string name;
};
  1. 动物派生类
    ①.Dog 类
#include "animal.h"

class Dog : public Animal
{
public:
    using Animal::Animal;
    void accept(Visitor *m_visitor) override;
};

#include "dog.h"
#include "visitor.h"

void Dog::accept(Visitor *m_visitor)
{
    m_visitor->visit(this);
}

②.Cat 类

#include "animal.h"

class Cat : public Animal
{
public:
    using Animal::Animal;
    void accept(Visitor *m_visitor) override;
};

#include "cat.h"
#include "visitor.h"

void Cat::accept(Visitor *m_visitor)
{
    m_visitor->visit(this);
}
  1. 访问者基类
#include <iostream>
class Dog;
class Cat;
class Visitor
{
public:
    Visitor(){};
    virtual ~Visitor(){}
    virtual void visit(Dog * animal) = 0;
    virtual void visit(Cat * animal) = 0;
};
  1. 访问者派生类
    ①.叫 访问者
#include "visitor.h"

class SpeakVisitor : public Visitor
{
public:
    SpeakVisitor(){}
    void visit(Cat *animal) override;
    void visit(Dog *animal) override;
};

#include "speakvisitor.h"
#include "cat.h"
#include "dog.h"

void SpeakVisitor::visit(Cat *animal)
{
    cout << animal->getName()+"叫:喵喵~"<<endl;
}

void SpeakVisitor::visit(Dog *animal)
{
     cout << animal->getName()+"叫:汪汪~"<<endl;
}

②.跑 访问者

#include "visitor.h"

class RunVisitor : public Visitor
{
public:
    RunVisitor(){}
    void visit(Dog *animal) override;
    void visit(Cat *animal) override;
};

#include "runvisitor.h"
#include "dog.h"
#include "cat.h"

void RunVisitor::visit(Dog *animal)
{
    cout << animal->getName()+"跑:一蹦一蹦~"<<endl;
}

void RunVisitor::visit(Cat *animal)
{
     cout << animal->getName()+"跑:一跳一跳~"<<endl;
}
  1. 动物园类
#include "animal.h"
#include "visitor.h"
#include <list>
#include <memory>
using namespace std;

class Zoo
{
public:
    Zoo(){};
    void addAnimal(shared_ptr<Animal> animal)
    {
        animals.push_back(animal);
    }
    void RemoveAnimal(shared_ptr<Animal> animal)
    {
        animals.remove(animal);
    }
    void accept(Visitor * visitor)
    {
        for(auto &animal:animals  )
        {
            animal->accept(visitor);
        }
    }

private:
    list<shared_ptr<Animal>> animals;
};
  1. 客户端调用
    在这里插入图片描述
#include "dog.h"
#include "runvisitor.h"
#include "speakvisitor.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Zoo *zoo = new Zoo ();
    shared_ptr<Dog> dog1(new Dog("泰迪"));
    shared_ptr<Dog> dog2(new Dog("哈士奇"));
    shared_ptr<Cat> cat1(new Cat("波斯猫"));
    shared_ptr<Cat> cat2(new Cat("HelloKitty"));

    zoo->addAnimal(dog1);
    zoo->addAnimal(dog2);
    zoo->addAnimal(cat1);
    zoo->addAnimal(cat2);

    cout << "所有动物开始叫:"<<endl;
    SpeakVisitor * speak = new SpeakVisitor () ;
    zoo->accept(speak);
    cout << endl;
    zoo->RemoveAnimal(cat1);//移除一个对象
    cout << "所有动物开始跑:"<<endl;
    RunVisitor * run = new RunVisitor();
    zoo->accept(run);

    return a.exec();
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值