zoukankan      html  css  js  c++  java
  • 组合模式(C++)

      组合模式:将对象组合成树形结构以来表示"整体--部分"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

      关于组合模式的定义有个关键词"树形",这个很关键,也很常见,如二叉树什么的。举个例子,如孝感城市,有教育部分和检察部门,孝感市下面的又有大悟县、红安县等县城,每个县城下面也有教育部分和检察部门,这个不就是一个树形结构吗(当然,还可以在县城叶子下面产生镇,镇也有教育部门和监察部门,这里仅仅是为了演示组合模式,叶子节点到县城这里就不在继续....)?

      用C++来实现,我们可以定义一个City的基类,里面定义两个add和diaplay函数,其中add用来添加city的对象,display主要是为了打印结果来看看"树形";再定义个一个指定的城市类,继承自City,并实现add和display方法;最后定义个教育部门类EducationBureau和监察部门类SupervisionBureau,并实现display方法(add方法不实现,我们假设已经到最下面的叶子节点)。说起来可能不大明白,我们用UML类图来看看呗:

    再来来点代码就应该更有助于理解了:

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    class City//城市的基类
    {
    protected:
        string m_str;
    public:
        City(string str):m_str(str){}
        virtual ~City(){}
        virtual void add(City* city){}
        virtual void display(int dep){}
    };
    
    class SpecifiedCity : public City //具体城市
    {
    private:
        vector<City*> m_list_city;
    public:
        SpecifiedCity(string str):City(str){}
        ~SpecifiedCity(){}
        void add(City* city)
        {
            m_list_city.push_back(city);
        }
        void display(int dep)
        {
            for(int i=0; i<dep; i++)
            {
                cout<<"*";
            }
            cout<<m_str<<endl;
            vector<City*>::iterator iter;
            for(iter = m_list_city.begin(); iter != m_list_city.end(); iter++)
            {
                (*iter)->display(dep+2);//此处+2完全是为了表示树形结构,并无其他含义
            }
        }
    };
    
    class EducationBureau : public City //教育部
    {
    public:
        EducationBureau(string str):City(str){}
        virtual ~EducationBureau(){}
        void display(int dep)
        {
            for(int i=0; i<dep; i++)
            {
                cout<<"*";
            }
            cout<<m_str<<endl;
        }
    };
    
    class SupervisionBureau : public City//监察部
    {
    public:
        SupervisionBureau(string str):City(str){}
        virtual ~SupervisionBureau(){}
        void display(int dep)
        {
            for(int i=0; i<dep; i++)
            {
                cout<<"*";
            }
            cout<<m_str<<endl;
        }
    };
    
    int main(int argc, char** argv)
    {
        City *pRoot =new SpecifiedCity("孝感市");
        City* pLeafA = new EducationBureau("教育部门");
        City* pLeafB = new SupervisionBureau("监察部门");
        pRoot->add(pLeafA);
        pRoot->add(pLeafB);
        pRoot->display(1);
    
        City *pRootA = new SpecifiedCity("大悟县");
        City* pLeafC = new EducationBureau("教育部门");
        City* pLeafD = new SupervisionBureau("监察部门");
        pRootA->add(pLeafC);
        pRootA->add(pLeafD);
        pRootA->display(4);
    
        City *pRootB = new SpecifiedCity("红安县");
        City* pLeafE = new EducationBureau("教育部门");
        City* pLeafF = new SupervisionBureau("监察部门");
        pRootB->add(pLeafE);
        pRootB->add(pLeafF);
        pRootB->display(4);
    
        delete pRoot; delete pLeafA; pLeafB;
        delete pRootA; delete pLeafC; pLeafD;
        delete pRootB; delete pLeafE; pLeafF;
    
        return 0;
    }

    要时还是不是很明白,那就看输出的"树形"结果吧:

       以上代码在VS2013上编译通过。

      以上的delete对象有点多哈,感觉有点笨。我开始想的使用智能指针来创建对象,但是最后添加时报错,调试了十来分钟没有弄好就没有弄,后面有时间再加上去,如果哪位大侠用智能指针实现了,麻烦发给我看看,我也想学习学习...........

  • 相关阅读:
    servlet上传图片 服务器路径(转)
    图片和提交servlet的相对和绝对路径
    Intel 的面试经历中国研究院
    CentOS-6.5-x86_64 最小化安装,已安装包的总数,这些包?
    西门子PLC学习笔记8-(计时器)
    这个周末我太累了
    windows7股票的,win8残疾人,安装Han澳大利亚sinoxn个时间,sinox它支持大多数windows软体
    net.sf.json 迄今 时刻 格式 办法
    ar命令提取.a时刻,一个错误 is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
    POJ 2187: Beauty Contest(旋转卡)
  • 原文地址:https://www.cnblogs.com/huiz/p/8444406.html
Copyright © 2011-2022 走看看