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

  • 相关阅读:
    WPF 文本滚动效果 渐变效果
    Unity3D 学习——入门资料整理
    命名管道 问题:信号灯超时问题
    Nginx 遇到的问题
    Nginx的安装配置 例子
    03 Spring的父子容器
    02 浅析Spring的AOP(面向切面编程)
    03 JVM的垃圾回收机制
    02 Java类的加载机制
    01 深入理解JVM的内存区域
  • 原文地址:https://www.cnblogs.com/huiz/p/8444406.html
Copyright © 2020-2023  润新知