C++设计模式——访问者模式(高屋建瓴)

原文 https://blog.csdn.net/CoderAldrich/article/details/83270301
我敲了代码 做出一些修改

在GOF的《设计模式:可复用面向对象软件的基础》一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。该模式的目的是要把处理从数据结构分离出来。访问者模式让增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中
在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>//包含find函数
using namespace std;

class ConcreteElementA;
class ConcreteElementB;

class Visitor {
 public:
   virtual void VisitConcreteElementA(ConcreteElementA *elementA) = 0;
   virtual void VisitConcreteElementB(ConcreteElementB *elementB) = 0;

};

class ConcreteVisitor1 : public Visitor {
 public:
   void VisitConcreteElementA(ConcreteElementA *elementA);
   void VisitConcreteElementB(ConcreteElementB *elememtB);
};

void ConcreteVisitor1::VisitConcreteElementA(ConcreteElementA *elementA) {
  cout << "ConcreteVisitor1 ConcreteElEmentA" << endl;
}

void ConcreteVisitor1::VisitConcreteElementB(ConcreteElementB *elememtB) {
  cout << "ConcreteVisitor1 ConcreteElementB" << endl;
}

class ConcreteVisitor2 : public Visitor {
 public:
   void VisitConcreteElementA(ConcreteElementA *elementA);
   void VisitConcreteElementB(ConcreteElementB *elememtB);
};

void ConcreteVisitor2::VisitConcreteElementA(ConcreteElementA *elementA) {
  cout << "ConcreteVisitor2 ConcreteElEmentA" << endl;
}

void ConcreteVisitor2::VisitConcreteElementB(ConcreteElementB *elememtB) {
  cout << "ConcreteVisitor2 ConcreteElementB" << endl;
}

class Element {
 public:
   virtual void Accept(Visitor *visitor) = 0;
};

class ConcreteElementA : public Element {
 public:
   void Accept(Visitor *visitor);
};

void ConcreteElementA::Accept(Visitor *visitor) {
  visitor->VisitConcreteElementA(this);
}

class ConcreteElementB : public Element {
 public:
   void Accept(Visitor *visitor);
};

void ConcreteElementB::Accept(Visitor *visitor) {
  visitor->VisitConcreteElementB(this);
}

class ObjectStruture {
 public:
  void Attach(Element *element);
  void Detach(Element *element);
  void Accept(Visitor *visitor);

 private:
  vector<Element *> elements_;
};

void ObjectStruture::Attach(Element *element) {
  elements_.push_back(element);
}

void ObjectStruture::Detach(Element *element) {
  vector<Element *>::iterator it = find(elements_.begin(), elements_.end(), element);
  if (it != elements_.end()) {
    elements_.erase(it);
  }
}

void ObjectStruture::Accept(Visitor *visitor) {
  for (vector<Element *>::iterator it = elements_.begin(); \
          it != elements_.end(); it++) {

    (*it)->Accept(visitor);
  }
}

int main() {

  ObjectStruture *object = new ObjectStruture;
  ConcreteElementA *elementA = new ConcreteElementA;
  ConcreteElementB *elementB = new ConcreteElementB;

  object->Attach(elementA);
  object->Attach(elementB);
  
  ConcreteVisitor1 *visitor1 = new ConcreteVisitor1;
  ConcreteVisitor2 *visitor2 = new ConcreteVisitor2;

  object->Accept(visitor1);
  object->Accept(visitor2);
  
  if (visitor1) {
    delete visitor1;
  }

  if (visitor2) {
    delete visitor2;
  }

   if (elementA) {
    delete elementA;
  }

  if (elementB) {
    delete elementB;
  }
}

输出结果:

ConcreteVisitor1 ConcreteElEmentA
ConcreteVisitor1 ConcreteElementB
ConcreteVisitor2 ConcreteElEmentA
ConcreteVisitor2 ConcreteElementB

原网址:https://blog.csdn.net/finghting321/article/details/105431949

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std; 
class Element;
class ConcreteElementA;
class ConcreteElementB;
// 访问者
class Visitor{
 public:
  virtual void VisitConcreteElementA(ConcreteElementA * p) = 0;
  virtual void VisitConcreteElementB(ConcreteElementB * p) = 0;
};
// 被访问元素: 定义一个Accept操作,它以一个访问者为参数
class Element {
 public:
  Element(std::string str) {
	m_strName_ = str;
  }
  std::string getName() {
	return m_strName_;
  }
  virtual void Accept(Visitor * visitor) = 0;
 protected:
  std::string m_strName_;
};
//具体元素A:实现Accept操作,该操作以一个访问者为参数
class ConcreteElementA : public Element {
 public:
  ConcreteElementA(std::string str) : Element(str) {}
  void Accept(Visitor * visitor);
};
void ConcreteElementA::Accept(Visitor * visitor) {
  visitor->VisitConcreteElementA(this);
}
//具体元素B
class ConcreteElementB : public Element {
 public:
  ConcreteElementB(std::string str) : Element(str) {}
  void Accept(Visitor * visitor);
};
void ConcreteElementB::Accept(Visitor * visitor) {
  visitor->VisitConcreteElementB(this);
}
// 聚集类对象结构:能够枚举它的元素,同时提供一个高层的接口以允许该访问者访问它的元素
class ObjectStructure {
 private:
  std::vector<Element *> m_vec_;
 public:
  ~ObjectStructure() {
	for (auto it = m_vec_.begin(); it != m_vec_.end(); it++) {
	  delete *it;
	}
	m_vec_.clear();
  }
  void add(Element * p) {
    m_vec_.push_back(p);
  }
  void accept(Visitor * visitor) {
	for (auto it = m_vec_.cbegin(); it != m_vec_.cend(); it++) {
	  (*it)->Accept(visitor);
	}
  }
};

//具体访问者A
class ConcreteVisitorA : public Visitor {
 public:
  void VisitConcreteElementA(ConcreteElementA * p) {
    std::cout << "ConcreteVisitorA FangWenLe" << p->getName() << std::endl;
  }
  void VisitConcreteElementB(ConcreteElementB * p) {
    std::cout << "ConcreteVisitorA FangWenLe" << p->getName() << std::endl;
  }
};
//具体访问者B
class ConcreteVisitorB : public Visitor {
 public:
  void VisitConcreteElementA(ConcreteElementA * p) {
	std::cout << "ConcreteVisitorB FangWenLe" << p->getName() << std::endl;
  }
  void VisitConcreteElementB(ConcreteElementB * p) {
    std::cout << "ConcreteVisitorB FangWenLe" << p->getName() << std::endl;
  }
};

int main() {
  // 访问者模式
  ObjectStructure * p = new ObjectStructure();
  p->add(new ConcreteElementA("A"));
  p->add(new ConcreteElementB("B"));
  
  ConcreteVisitorA * pVisitorA = new ConcreteVisitorA();
  ConcreteVisitorB * pVisitorB = new ConcreteVisitorB();
 
  p->accept(pVisitorA);
  p->accept(pVisitorB);
 
  delete pVisitorA;
  delete pVisitorB;
  delete p;
  return 0;
}

输出结果:

ConcreteVisitorA FangWenLeA
ConcreteVisitorA FangWenLeB
ConcreteVisitorB FangWenLeA
ConcreteVisitorB FangWenLeB

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值