Composite

7251 ワード

#include <vector>

#include <iostream>



using namespace std;







#define DO_NOTHING()

#define DESTROY_POINTER(ptr) if (ptr) { delete ptr; ptr = NULL; }







class Component

{

    friend class Composite;

    friend class Leaf;

public:

    virtual void Whoami()=0;

    virtual void AddChild(Component* pChild)=0;

    virtual void Whoareyou(int iIndex)=0;

    virtual void Travel(Component* pNode) = 0;

    

protected:

    vector<Component*> m_children;

};



class Composite : public Component

{

public:

    Composite() {}

    ~Composite();

    virtual void Whoami() { cout<<"I am a Composite"<<endl; }

    virtual void AddChild(Component* pChild) { m_children.push_back(pChild); }

    virtual void Whoareyou(int iIndex) { cout<<iIndex<<":"; m_children[iIndex]->Whoami(); }

    virtual void Travel(Component* pNode);

};









class Leaf : public Component

{

public:

    virtual void Whoami() { cout<<"I am a piece of Leaf"<<endl; }

    virtual void AddChild(Component* pChild) { DO_NOTHING(); }

    virtual void Whoareyou(int iIndex) { DO_NOTHING(); }

    virtual void Travel(Component* pNode) { Whoami(); }

};





Composite::~Composite()

{

    for (unsigned int i = 0; i < m_children.size(); i++)

    {

        Component* pTmp = m_children[i];

        DESTROY_POINTER(pTmp);

    }



    m_children.clear();

}



void Composite::Travel(Component* pNode)

{

    if (!pNode) pNode = this; // self

    pNode->Whoami();

    

    if (pNode->m_children.size() == 0) return ;

    

    for (unsigned int i = 0; i < pNode->m_children.size(); i++)

    {

        Travel(pNode->m_children[i]);

    }

}



int main(int argc, char *argv[])

{

    Component* pRoot, *pBranch1, *pBranch2;



    pRoot = new Composite;

    pRoot->AddChild(new Leaf);



    pBranch1 = new Composite;

    pRoot->AddChild(pBranch1);

    pBranch1->AddChild(new Leaf);

    pBranch1->AddChild(new Leaf);

     

    pBranch2 = new Composite;

    pBranch1->AddChild(pBranch2);

    pBranch2->AddChild(new Leaf);

    pBranch2->AddChild(new Leaf);

    pBranch2->AddChild(new Leaf);



    pRoot->Travel(NULL);



    DESTROY_POINTER(pRoot);

    DESTROY_POINTER(pBranch1);

    DESTROY_POINTER(pBranch2);



    return 0;

}