Visitor (Composite に追加)

#include <iostream>
#include <string>
#include <list>
using namespace std;
 
class Visitor;
 
class Component {
public:
	virtual void Display(int indent_num) = 0;
	// 追加
	virtual void Accept(Visitor *visitor) = 0;
protected:
	void indent(int num) {
		while (num--) {
			cout << "  ";
		}
	}
	string m_name;
};
 
 
class Leaf : public Component {
public:
	Leaf(const string &name) {
		m_name = name;
	}
	virtual void Display(int indent_num) {
		indent(indent_num);
		cout << "- Leaf (" << m_name.c_str() << ")" << endl;
	}
	// 追加
	virtual void Accept(Visitor *visitor);
	string GetName() {
		return m_name;
	}
};
 
 
class Composite : public Component {
public:
	Composite(const string &name) {
		m_name = name;
	}
	virtual ~Composite() {
		list<Component*>::iterator it = m_childs.begin();
		while (it != m_childs.end()) {
			delete *it++;
		}
	}
	virtual void Display(int indent_num) {
		indent(indent_num);
		cout << "+ Composite (" << m_name.c_str() << ")" << endl;
		list<Component*>::iterator it = m_childs.begin();
		while (it != m_childs.end()) {
			++indent_num;
			(*it++)->Display(indent_num);
			--indent_num;
		}
	}
	void Add(Component *obj) {
		m_childs.push_back(obj);
	}
	// 追加
	virtual void Accept(Visitor *visitor);
	string GetName() {
		return m_name;
	}
protected:
	list<Component*> m_childs;
};
 
 
//// 追加 visitor pattern
 
class Visitor {
public:
	virtual void Visit(Leaf *component) = 0;
	virtual void Visit(Composite *component) = 0;
};
 
class ConcreteVisitor : public Visitor {
public:
	virtual void Visit(Leaf *component) {
		cout << "[Leaf] " << component->GetName().c_str() << endl;
	}
	virtual void Visit(Composite *component) {
		cout << "[Dir] " << component->GetName().c_str() << endl;
	}
};
 
 
////// 追加
void Leaf::Accept(Visitor *visitor) {
	visitor->Visit(this);
}
 
void Composite::Accept(Visitor *visitor) {
	visitor->Visit(this);
	list<Component*>::iterator it = m_childs.begin();
	while (it != m_childs.end()) {
		(*it++)->Accept(visitor);
	}
}
 
 
int main() {
	Composite *root_dir = new Composite("root_dir");
	Composite *in_dir = new Composite("in_dir");
 
	root_dir->Add(in_dir);
	root_dir->Add(new Leaf("file1"));
 
	in_dir->Add(new Leaf("file2"));
	in_dir->Add(new Leaf("file3"));
 
	//root_dir->Display(0);
	//in_dir->Display(0);
 
	ConcreteVisitor *visitor = new ConcreteVisitor;
	root_dir->Accept(visitor);
	//in_dir->Accept(visitor);
	delete visitor;
 
	delete root_dir;
	return 0;
}
 



参考サイト

デザインパターンを“喩え話”で分かり易く理解する
http://www.netlaputa.ne.jp/~hijk/study/oo/designpattern.html



デザインパターンの骸骨たち
http://www002.upp.so-net.ne.jp/ys_oota/mdp/
最終更新:2011年11月17日 22:51