#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;
}
参考サイト
最終更新:2011年11月17日 22:51