首页 > 编程语言 >C++ 设计模式之组合模式

C++ 设计模式之组合模式

时间:2023-07-07 13:47:49浏览次数:34  
标签:std ComponentPtr 组合 void C++ add vec 设计模式 ptr

设计模式之组合模式

  组合模式,将对象组合成属性结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。其UML图如下:

  一个组织有很多子组织,而无论子组织是单独一个部门或是一个分组织。该组织都希望把它们当成一样的子组织来管理。举个例子吧,就拿公司来说吧,一个公司总部为了方便管理希望把分公司当成一个部门来管理就行了。比如公司要发奖金了,总公司只用通知自己的所有部门就可以了。对于分公司,只用通知分公司就可以了,而不用一一通知分公司的各个部门。具体的实现就是Composite中有一个自己子组织的列表,当有什么通知要执行时,按顺序通知列表中的子组织就行了。而如果子组织中有组织的话也时执行相同的操作,因为它们都实现了相同的接口。

示例代码如下:

 1 // CompositeModel.h文件
 2 #pragma once
 3 #include <iostream>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 
 8 class ComponentPtr
 9 {
10 protected:
11     std::string m_strName;
12 public:
13     ComponentPtr(std::string str)
14     {
15         m_strName = str;
16     }
17     virtual void add(ComponentPtr * p) = 0;
18     virtual void remove(ComponentPtr * p) = 0;
19     virtual void display() = 0;
20 };
21 
22 class LeafPtr : public ComponentPtr
23 {
24 public:
25     LeafPtr(std::string str) : ComponentPtr(str) {}
26     void add(ComponentPtr * p)
27     {
28         std::cout << "Leaf cannot add" << std::endl;
29     }
30     void remove(ComponentPtr * p)
31     {
32         std::cout << "Leaf cannot remove" << std::endl;
33     }
34     void display()
35     {
36         std::cout << m_strName << std::endl;
37     }
38 };
39 
40 class CompositePtr : public ComponentPtr
41 {
42 private:
43     // 这里使用智能指针不用自己释放new的内存
44     std::vector<std::shared_ptr<ComponentPtr>> m_vec;
45 public:
46     CompositePtr(std::string str) : ComponentPtr(str) {};
47     ~CompositePtr()
48     {
49         if (!m_vec.empty())
50         {
51             m_vec.clear();
52         }
53     }
54     void add(ComponentPtr * p)
55     {
56         auto it = find_if(m_vec.begin(), m_vec.end(), 
57             [p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
58         if (it == m_vec.end())
59             m_vec.push_back(std::shared_ptr<ComponentPtr>(p));
60     }
61     void remove(ComponentPtr * p)
62     {
63         auto it = find_if(m_vec.begin(), m_vec.end(),
64             [p](std::shared_ptr<ComponentPtr> ptr) {return p == ptr.get(); });
65         if (it == m_vec.end())
66             return;
67         m_vec.erase(it);
68     }
69     void display()
70     {
71         for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
72         {
73             (*it)->display();
74         }
75     }
76 };

测试代码如下:

 1 #include <iostream>
 2 #include "CompositeModel.h"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7     // 组合模式
 8     CompositePtr * p = new CompositePtr("总部");
 9     p->add(new LeafPtr("总部财务部门"));
10     p->add(new LeafPtr("总部人力资源部门"));
11     CompositePtr * p1 = new CompositePtr("上海分部");
12     p1->add(new LeafPtr("上海分部财务部门"));
13     p1->add(new LeafPtr("上海分部人力资源部门"));
14     p->add(p1);
15     p->display();
16     getchar()
17     return 0;
18 }

测试结果如下图:

当你发现需求中是体现部分于整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,同意使用组合结构中的所有对象时,就应该考虑使用组合模式了。

标签:std,ComponentPtr,组合,void,C++,add,vec,设计模式,ptr
From: https://www.cnblogs.com/ybqjymy/p/17534723.html

相关文章

  • C++ 设计模式之单例模式
    设计模式之单例模式保证一个类仅有一个实例,并提供一个访问他的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且可以提供一个访问该实例......
  • C++学生健康信息收集系统[2023-07-06]
    C++学生健康信息收集系统[2023-07-06]学生健康信息收集系统简介一、 问题描述为了应对新型冠状病毒疫情,学校需要开发一个能够每天收集全校学生健康信息的系统,便于学校管理。不同学院以及学校的管理员,需要能方便地查看和导出健康状况异常的学生列表,并能对各类信息进行查看和统计......
  • C/C++学生通讯录管理系统[2023-07-06]
    C/C++学生通讯录管理系统[2023-07-06]一、设计要求1、题目利用C++语言实现一个学生通讯录管理系统,系统中需要实现的功能如下:(1)添加学生信息:向通讯录中添加新人,信息包括(学生姓名、性别、年龄、联系电话、家庭住址等),最多记录100人。(2)显示学生信息:显示通讯录中所有学生信息。(3)删......
  • C++ 设计模式之桥接模式
    设计模式之桥接模式桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。这里说的实现分离,并不是说然抽象类与派生类分离,这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。其UML图如下: 结合上图理解一下其定义。抽象部分指的是Abstraction......
  • C/C++订餐管理系统[2023-07-07]
    C/C++订餐管理系统[2023-07-07]1、订餐管理系统要求实现饭店的订餐信息管理,包括菜单管理、订单管理、统计分析。实现菜单信息(菜号、菜名、价格、成本)的增删改查;实现订单管理(订单号、就餐人数、下单时间、订单总价、订单包含的所有菜品(菜号、数量))。系统功能包括以下方面:A、菜......
  • 学习C++这一篇就够了(进阶篇)
    ​内存模型C++在执行程序的时候,将内存方向划分为4个区域:代码区:存放二进制代码,由操作系统进行管理全局区:存放全局变量、静态变量、常量,程序结束后由操作系统释放栈区:存放函数参数、局部变量,由编译器自动分配和释放堆区:由开发者申请分配和释放,若程序员不释放,程序结束由......
  • C++ 中的函数重载
     在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。https://www.121mu.com/bkjq211/......
  • C++ 多态
     多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。下面的实例中,基类Shape被派生为两个类https://www.121mu.com/czss/......
  • C++ 中的运算符重载
     您可以重定义或重载大部分C++内置的运算符。这样,您就能使用自定义类型的运算符。重载的运算符是带有特殊名称的函数,函数名是由关键字operator和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。https://www.micsoon.com/bkzn19/......
  • C++ std::chrono 计时器的使用
    使用标准库 #include<chrono>intmain(){ autostampBeg=std::chrono::steady_clock::now(); //dosometing Sleep(2400); autostampEnd=std::chrono::steady_clock::now(); doubletime_second=std::chrono::duration<double>(stampEnd-sta......