Composite模式--结构型模式
#ifndef COMPOSITE_H_
#define COMPOSITE_H_
#include <list>
// 提供接口的抽象基类
class Component
{
public:
Component() {}
virtual ~Component () {}
/*
因为Component的每个子类无论是Leaf还是Composite都必须实现自己版本的
operation()函数,所以定义为纯虚函数。
*/
// 纯虚函数只提供接口不提供默认实现
virtual void operation() = 0;
/*
因为下面这几个函数只有Composite类才实现自己的版本,
而Leaf类继承了这几个接口后不做任何事情,所以提供默认实现,
之所以声明为虚函数是为了让Composite类继承后可以实现自己
版本的这个函数。
*/
// 虚函数提供默认实现,但是什么也不做
virtual void add(Component* lhs);
virtual void remove(Component* lhs);
virtual Component* get_child(int i);
};
// 派生自Component,是其中叶子组件的基类
class Leaf : public Component
{
public:
Leaf() {}
virtual ~Leaf() {}
virtual void operation();
};
// 派生自Component,是其中含有子件的组件的基类
class Composite : public Component
{
public:
Composite() {}
virtual~Composite();
virtual void operation();
virtual void add(Component* lhs);
virtual void remove(Component* lhs);
virtual Component* get_child(int i);
private:
// 存储它的子组件的容器
std::list<Component*> lst_;
};
#endif
#include "Composite.h"
#include <iostream>
void Component::add(Component* lhs) {}
void Component::remove(Component* lhs) {}
Component* Component::get_child(int i) {return 0;}
void Leaf::operation()
{
std::cout<<"leaf operation!"<<std::endl;
}
Composite::~Composite()
{
Component* tmp = 0;
std::list<Component*>::iterator begin = lst_.begin();
while(begin != lst_.end())
{
tmp = *begin;
delete tmp;
begin++;
}
}
void Composite::operation()
{
std::list<Component*>::iterator begin = lst_.begin();
while(begin != lst_.end())
{
(*begin)->operation();
begin++;
}
}
void Composite::add(Component* lhs)
{
lst_.push_back(lhs);
}
void Composite::remove(Component* lhs)
{
lst_.remove(lhs);
}
Component* Composite::get_child(int i)
{
std::list<Component*>::iterator begin = lst_.begin();
for(int j =0; j<i; j++)
begin++;
return *begin;
}
#include "Composite.h"
int main()
{
Component* p1 = new Leaf;
Component* p2 = new Composite;
Component* p3 = new Leaf;
Component* p4 = new Leaf;
p2->add(p3);
p2->add(p4);
p1->operation();
p2->operation();
p2->get_child(1)->operation();
delete p1;
delete p2;
return 0;
}