9、组合模式(结构性模式)

        组合模式又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构,以一致的方式处理叶子对象以及组合对象,不以层次高低定义类,都是结点类

       一、传统组合模式

        举例,大学、学院、系,它们之间不是继承关系,是组合关系:大学由学院组成,学院由系组成,但是它们都是组织结点,一个大学,n个学院,一个学院m个系,大学、学院是 组合类型的,它们都包含结点成员,系是 叶子类型 的,不包含结点成员

        把大学类、学院类、系类抽象为组织结点类,它们都是组织结点类的子类(其中大学子类、学院子类是组合类型的类,系是叶子类型的类),按照具体依赖抽象原则,以子类共有的属性和行为来定义结点类,代码如下:

//组织结点(基类)Organization
class Organization{                      //具体依赖抽象原则std::string name;//数据成员
public:Organization( std::string name):name(name) { }//构造函数virtual ~Organization(){ }                    //虚析构//其他成员函数virtual std::string getName(){ return name; }   virtual void add(Organization* o){ throw "叶子结点没有成员!\n"; }//virtual void remove( ){ throw "叶子结点没有成员!\n";  }virtual void print() = 0;  //
};    

        组合类型的子类University、College,重写基类成员函数,代码几乎一样

//组合类型(子类)University College
//University
class University:public Organization{std::list<Organization*> ul; //以基类的形式包含其他子类对象
public:University(std::string name):Organization(name) { }~University(){std:: cout << "~University\n";for(auto o:ul){ delete o; }		}//重写virtual void add(Organization* o){ul.push_back(o);}virtual void print(){std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分for( auto o:ul ){o->print();}}	
};//College
class College:public Organization{std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:College(std::string name):Organization(name) { }~College(){std:: cout << "~College\n";for(auto o:cl){ delete o; }		}//重写virtual void add(Organization* o){cl.push_back(o);}virtual void print(){std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分for( auto o:cl ){o->print();}}	
};

        叶子类型的子类(Department)

//叶子类型(子类)Department
class Department:public Organization{
public:Department(std::string name):Organization(name) { }~Department(){std:: cout << "~Department\n";}//重写virtual void print(){std::cout << getName() << "\n";}
};

        头文件及测试代码

#include <iostream>
#include <string>
#include <exception>
#include <list>int main() 
{University u("清华大学");Organization* c1 = new College("计算机学院");Organization* c2 = new College("信息工程学院");Organization* d = new Department("信息工程");u.add( c1 );u.add( c2 );c2->add( d );u.print();//c2->print();	return 0;
}

        二、组合模式的结点设计

        把组合类型的的属性、行为都放到结点,以对象组是否为空来判断是叶子类型的还是组合类型的,这样叶子类型也可以扩展为组合类型,虽然看起来有点混乱,但是确实可行,比如系原来是叶子,现在有了个学生会,添加成员后就可以不是叶子了

#include <iostream>
#include <string>
#include <exception>
#include <list>//组织结点(基类)Organization
class Organization{  //具体依赖抽象原则std::string name;//数据成员std::list<Organization*> ol; //对象组
public:Organization( std::string name):name(name) { } //构造函数virtual ~Organization(){	 //虚析构for(auto o:ol){ delete o; }	}                    //其他成员函数 virtual void add(Organization* o){ ol.push_back(o); }	virtual void print(){std::cout << name << "\n";if( !ol.empty() ) //判断是否是叶子结点{ for( auto o:ol ){o->print();}}	}
};    //University
class University:public Organization{
public:University(std::string name):Organization(name) { }~University(){ std:: cout << "~University\n"; }
};//College
class College:public Organization{std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:College(std::string name):Organization(name) { }~College(){std:: cout << "~College\n";}
};//Department
class Department:public Organization{
public:Department(std::string name):Organization(name) { }~Department(){std:: cout << "~Department\n";}
};//StudentUnion
class StudentUnion:public Organization{
public:StudentUnion(std::string name):Organization(name) { }~StudentUnion(){std:: cout << "~StudentUnion\n";}
};int main() 
{University u("清华大学");Organization* c1 = new College("计算机学院");Organization* c2 = new College("信息工程学院");Organization* d1 = new Department("信息工程");Organization* d2 = new Department("软件工程");Organization* s = new StudentUnion("信息工程学生会");d1->add( s );c1->add( d2 );c2->add( d1 );u.add( c1 );u.add( c2 );u.print( );//c2->print( );	return 0;
}

        三、修改打印函数,打印出树形结构

         1、 修改print

    virtual void print( int depth ){for(int i=0; i< depth; ++i)std:: cout << "--";std::cout << name << "\n";if( !ol.empty() ) //判断是否是叶子结点{ for( auto o:ol ){o->print(depth+1);}}	}

        2、调用修改为

u.print(0);
//c2->print( 0 );

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536350.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录 前言一、使用 stb_image 库加载纹理图片1. 获取 stb_image.h 头文件2. 使用 stb_image.h 中的相关接口加载纹理图片3. 纹理图片——cordeBouee4.jpg二、渲染使用纹理贴图的旋转 3D 立方体1. egl_wayland_texture_cube.c2. Matrix.h 和 Matrix.c3. xdg-shell-client-pr…

《C语言都有哪些字符串处理函数?》

目录 17个字符串处理函数 1. gets()--读 2.fgets()--从指定文件内读 3.puts()--输出 4.fputs()--写入到指定文件中 5.strlen()--计算字符串长度 6.strcpy()--复制 7.strncpy()--复制前n个字符 8.strcat()--字符串连接 9.strncat()--将前n个字符连接 10.strcmp()--比…

带你摸透C语言相关内存函数

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

【论文阅读】Vision Mamba:双向状态空间模型的的高效视觉表示学习

文章目录 Vision Mamba:双向状态空间模型的的高效视觉表示学习摘要介绍相关工作用于视觉应用的状态空间模型 方法准备视觉MambaVim块结构细节高效分析计算效率 实验图片分类语义分割目标检测和实例分割消融实验双向SSM分类设计 总结和未来工作 论文地址&#xff1a; Vision Mam…

人工智能测试开发

随着人工智能在各行各业的广泛应用&#xff0c;学习并掌握AI技术在软件测试中的应用变得至关重要。不仅能使你跟上行业的发展趋势&#xff0c;还能提升你的竞争力。而且&#xff0c;市场对具备AI测试技能的测试工程师的需求正日益增长&#xff0c;这使得掌握这些技能能够帮助你…

蓝桥杯算法训练VIP-数组查找及替换

题目 1634: 蓝桥杯算法训练VIP-数组查找及替换 时间限制: 3s 内存限制: 192MB 提交: 1629 解决: 890 题目描述 给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素&#xff0c;同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间&#xff0…

C++初阶

1.缺省参数 给缺省参数的时候&#xff0c;不能声明&#xff0c;定义同时给&#xff0c;只能声明的时候给缺省参数&#xff0c;同时给程序报错&#xff1b; 2.函数重载 C语言不允许同名函数的存在&#xff0c;函数名不能相同&#xff0c;C引入函数重载&#xff0c;函数名可以…

GUI编程--PyQt5--QTabWidget

文章目录 组件使用信号样式设置 组件使用 QTabWidget 页签 信号 self._ui Ui_Sub() self._ui.setupUi(right) # 切换tab页 self._ui.tabWidget.currentChanged.connect(self.tab_slot)def tab_slot(self):cur_index self._ui.tabWidget.currentIndex()tab_name self._ui…

InstantID Zero-shot Identity-Preserving Generation in Seconds

InstantID: Zero-shot Identity-Preserving Generation in Seconds TL; DR&#xff1a;InstantID IP-Adapter (Face) ControlNet&#xff0c;实现了具有较高保真度的人脸 ID 生成。 方法 InstantID 想做到的事情是&#xff1a;给定一张参考人脸 ID 图片&#xff0c;生成该…

24计算机考研调剂 | 东北石油大学

东北石油大学智能物探团队招生宣传 考研调剂招生信息 学校:东北石油大学 专业:工学->地质资源与地质工程->矿产普查与勘探 年级:2024 招生人数:2 招生状态:正在招生中 联系方式:********* (为保护个人隐私,联系方式仅限APP查看) 补充内容 团队介绍&#xff1a; …

LeetCode543题:二叉树的直径(python3)

代码思路&#xff1a; 先递归调用左儿子和右儿子求得它们为根的子树的深度 L和 R &#xff0c;则该节点为根的子树的深度即为max(L,R)1。该节点的 dnode值为LR1 递归搜索每个节点并设一个全局变量 ans记录 dnode的最大值&#xff0c;最后返回 ans-1 即为树的直径。 # Definit…

编曲制作软件Fruity Loops Studio 21 中文版及新如何选择适合FL Studio 版本

如果你有着满腔的音乐才华&#xff0c;想要自己在家里发片吗&#xff1f;还是听 MOBY 的电子舞曲不过瘾&#xff0c;要再帮他做做 REMIX&#xff1f;有朋友会说&#xff0c;我不懂乐理&#xff0c;不懂五线谱&#xff0c;怎么制作音乐&#xff1f;这话说得很好&#xff0c;说到…