【C++设计模式】第八篇:组合模式(Composite)

注意:复现代码时,确保 VS2022 使用 C++17/20 标准以支持现代特性。

树形结构的统一操作接口


1. 模式定义与用途

核心思想

  • 组合模式:将对象组合成树形结构以表示“部分-整体”层次结构,使得客户端可以统一处理单个对象和组合对象。
  • 关键用途
    1.简化递归结构操作(如遍历目录树、渲染UI控件树)。
    2.隐藏复杂结构的差异,提供一致性接口。

​经典场景

  1. 文件系统管理(文件与文件夹的统一操作)。
  2. 图形界面容器(窗口包含按钮、面板等子控件)。

2. 模式结构解析

UML类图

+---------------------+  
|      Component      |  
+---------------------+  
| + add(c: Component) |  
| + remove(c: Component)|  
| + operation()       |  
+---------------------+  ^  |  +-------+-------+  |               |  
+-----------------+ +-----------------+  
|    Composite    | |      Leaf       |  
+-----------------+ +-----------------+  
| - children: list | | + operation()  |  
| + operation()    | +-----------------+  
+-----------------+  

角色说明

  1. Component:抽象接口,定义叶子和容器的共同操作(如add、remove)。
  2. Leaf:叶子节点,无子组件(如文件)。
  3. Composite:容器节点,存储子组件并实现递归逻辑(如文件夹)。

3. 简单示例:透明模式(统一接口)​

#include <iostream>  
#include <vector>  
#include <memory>  // 抽象组件(透明模式:叶子与容器接口一致)  
class FileSystemComponent {  
public:  virtual ~FileSystemComponent() = default;  virtual void add(std::shared_ptr<FileSystemComponent> item) {  throw std::runtime_error("叶子节点不支持此操作");  }  virtual void list() const = 0;  
};  // 叶子:文件  
class File : public FileSystemComponent {  
public:  File(const std::string& name) : name_(name) {}  void list() const override {  std::cout << "文件: " << name_ << "\n";  }  private:  std::string name_;  
};  // 容器:文件夹  
class Folder : public FileSystemComponent {  
public:  Folder(const std::string& name) : name_(name) {}  void add(std::shared_ptr<FileSystemComponent> item) override {  children_.push_back(item);  }  void list() const override {  std::cout << "文件夹: " << name_ << "\n";  for (const auto& child : children_) {  child->list();  }  }  private:  std::string name_;  std::vector<std::shared_ptr<FileSystemComponent>> children_;  
};  // 使用示例  
int main() {  auto root = std::make_shared<Folder>("根目录");  auto docs = std::make_shared<Folder>("文档");  auto file1 = std::make_shared<File>("简历.pdf");  auto file2 = std::make_shared<File>("笔记.txt");  docs->add(file1);  docs->add(file2);  root->add(docs);  root->list();  // 递归列出所有内容  
}  

4. 完整代码:安全模式与扩展功能

场景:图形界面控件树

#include <iostream>  
#include <vector>  
#include <memory>  
#include <algorithm>  // 抽象组件(安全模式:叶子与容器接口分离)  
class UIComponent {  
public:  virtual ~UIComponent() = default;  virtual void render() const = 0;  virtual std::string getName() const = 0;  
};  // 容器接口(仅容器支持添加/删除)  
class UIContainer : public UIComponent {  
public:  virtual void add(std::shared_ptr<UIComponent> child) = 0;  virtual void remove(std::shared_ptr<UIComponent> child) = 0;  
};  // 叶子:按钮  
class Button : public UIComponent {  
public:  Button(const std::string& name) : name_(name) {}  void render() const override {  std::cout << "渲染按钮: " << name_ << "\n";  }  std::string getName() const override {  return name_;  }  private:  std::string name_;  
};  // 容器:面板  
class Panel : public UIContainer {  
public:  Panel(const std::string& name) : name_(name) {}  void add(std::shared_ptr<UIComponent> child) override {  children_.push_back(child);  }  void remove(std::shared_ptr<UIComponent> child) override {  auto it = std::find(children_.begin(), children_.end(), child);  if (it != children_.end()) {  children_.erase(it);  }  }  void render() const override {  std::cout << "渲染面板: " << name_ << "\n";  for (const auto& child : children_) {  child->render();  }  }  std::string getName() const override {  return name_;  }  private:  std::string name_;  std::vector<std::shared_ptr<UIComponent>> children_;  
};  // 客户端代码  
int main() {  auto mainPanel = std::make_shared<Panel>("主面板");  auto button1 = std::make_shared<Button>("确定");  auto button2 = std::make_shared<Button>("取消");  auto subPanel = std::make_shared<Panel>("子面板");  auto button3 = std::make_shared<Button>("更多");  subPanel->add(button3);  mainPanel->add(button1);  mainPanel->add(button2);  mainPanel->add(subPanel);  mainPanel->render();  // 输出:  // 渲染面板: 主面板  // 渲染按钮: 确定  // 渲染按钮: 取消  // 渲染面板: 子面板  // 渲染按钮: 更多  
}  

5. 优缺点分析

优点​​缺点
统一处理简单与复杂对象透明模式违反接口隔离原则(叶子支持add)
支持递归操作与树形遍历容器需管理子节点生命周期,增加复杂度
灵活扩展新组件类型对性能敏感场景不友好(深层次遍历)

6. 调试与优化策略

调试技巧(VS2022)​

  1. 递归调用跟踪
    在render()方法内设置条件断点(如getName() == “子面板”)。
  2. 内存泄漏检测
    使用VS2022内置诊断工具(Debug > Windows > Memory Usage)。

性能优化

  1. 缓存遍历结果
class CachedPanel : public Panel {  
public:  void render() const override {  if (!cached_) {  cachedOutput_ = generateRenderOutput();  cached_ = true;  }  std::cout << cachedOutput_;  }  
private:  mutable bool cached_ = false;  mutable std::string cachedOutput_;  
};  
  1. 并行化渲染
#include <execution>  
void Panel::render() const {  std::for_each(std::execution::par, children_.begin(), children_.end(),  [](const auto& child) { child->render(); });  
}  

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

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

相关文章

【进程和线程】(面试高频考点)

【进程和线程】 前言 在计算机编程领域&#xff0c;并发编程是一项至关重要的技术&#xff0c;而进程和线程正是实现并发编程的核心概念。为了让大家更直观地理解并发编程的作用&#xff0c;我们先来看一个简单的生活例子。 想象一下&#xff0c;现在有一大份美味的饭菜&…

HTML 编辑器推荐与 VS Code 使用教程

在进行 HTML 编程时&#xff0c;选择一款合适的 HTML 编辑器能极大地提高开发效率。以下为大家推荐几款常用且功能强大的 HTML 编辑器&#xff0c;同时详细介绍如何使用 VS Code 创建和预览 HTML 文件。 一、HTML 编辑器推荐 VS Code&#xff1a;由微软开发&#xff0c;是一款…

Kubernetes开发环境minikube | 开发部署apache tomcat web集群应用

minikube是一个主要用于开发与测试Kubernetes应用的运行环境&#xff0c;本文主要描述在minikube运行环境中部署J2EE tomcat web应用。 单节点Node多Pod实例部署 如上所示&#xff0c;在minikube运行的Linux部署环境中启动单节点Node 如上所示&#xff0c;在minikube的容器环境…

STM32---FreeRTOS中断管理试验

一、实验 实验目的&#xff1a;学会使用FreeRTOS的中断管理 创建两个定时器&#xff0c;一个优先级为4&#xff0c;另一个优先级为6&#xff1b;注意&#xff1a;系统所管理的优先级范围 &#xff1a;5~15 现象&#xff1a;两个定时器每1s&#xff0c;打印一段字符串&#x…

永磁直驱式风力发电虚拟同步机仿真模型Matlab/Simulink模型

很久没有分享虚拟同步机控制相关的方向了&#xff0c;毕业后在电科院的项目又有所接触。这个课题方向其实作为硕士毕业课题还是够用的&#xff0c;相对来说也是比较容易毕业的&#xff0c;因为涉及的分支比较多。 后续对虚拟同步机的控制&#xff0c;我就延续我前面博客提到的方…

图像分类项目1:基于卷积神经网络的动物图像分类

1、选题背景及动机 在现代社会中&#xff0c;图像分类是计算机视觉领域的一个重要任务。动物图像分类具有广泛的应用&#xff0c;例如生态学研究、动物保护、农业监测等。通过对动物图像进行自动分类&#xff0c;可以帮助人们更好地了解动物种类、数量和分布情况&#xff0c;从…

Vue 3 整合 WangEditor 富文本编辑器:从基础到高级实践

本文将详细介绍如何在 Vue 3 项目中集成 WangEditor 富文本编辑器&#xff0c;实现图文混排、自定义扩展等高阶功能。 一、为什么选择 WangEditor&#xff1f; 作为国内流行的开源富文本编辑器&#xff0c;WangEditor 具有以下优势&#xff1a; 轻量高效&#xff1a;压缩后仅…

Ansys Zemax | 使用衍射光学器件模拟增强现实 (AR) 系统的出瞳扩展器 (EPE):第 4 部分

附件下载 联系工作人员获取附件 在 OpticStudio 中使用 RCWA 工具为增强现实&#xff08;AR&#xff09;系统设置出瞳扩展器&#xff08;EPE&#xff09;的示例中&#xff0c;首先解释了k空间中光栅的规划&#xff0c;并详细讨论了设置每个光栅的步骤。 介绍 本文是该四篇文…

CMake学习笔记(一):工程的新建和如何将源文件生成二进制文件

cmake是我们在工作过程中比较常见的一个工具&#xff0c;该系列文章是自己用来学习的笔记。目前只是记录下自己学习cmake的过程中的一些重要的知识点&#xff0c;其是以项目需求为导向并非完整的cmake的学习路线和系统&#xff0c;同样也并非适合所有的人。 1.生成一个可执行文…

libcoap在Ubuntu下的编译(基于CMake)

引言 libcoap 是一个开源的轻量级 C 语言库&#xff0c;用于实现 CoAP&#xff08;Constrained Application Protocol&#xff0c;受限应用协议&#xff09;。CoAP 是一种专为资源受限设备设计的轻量级通信协议&#xff0c;适用于物联网&#xff08;IoT&#xff09;和嵌入式系…

Docker新手入门(持续更新中)

一、定义 快速构建、运行、管理应用的工具。 Docker可以帮助我们下载应用镜像&#xff0c;创建并运行镜像的容器&#xff0c;从而快速部署应用。 所谓镜像&#xff0c;就是将应用所需的函数库、依赖、配置等应用一起打包得到的。 所谓容器&#xff0c;为每个镜像的应用进程创建…

蓝桥杯C组真题——巧克力

题目如下 思路 代码及解析如下 谢谢观看

SLAM评估工具安装及使用EVO(Ubuntu20.04安装evo)--缺少 onnx 库还有Pandas 版本不兼容解决

介绍一下我的是ubuntu20.04.机载电脑是orinnx&#xff0c;通过源码烧写的系统。 首先打开终端&#xff0c;输入 pip install evo --upgrade --no-binary evo 安装过程中出现如下问题 缺少 onnx 库还有Pandas 版本不兼容&#xff0c; ONNX&#xff08;Open Neural Network E…

在虚拟机上安装hadoop

在虚拟机上安装 Hadoop 是一个常见的实验环境搭建过程。以下是详细的步骤和注意事项&#xff1a; 前面的课程我们已经准备好了三台虚拟设备球供我们学习大数据技术&#xff0c;今天我们将使用其中的一台设备来运行第一个hadoop 程序。 运行第一个 hadoop程序 要运行 hadoop 程序…

Redis 常见数据类型

官方文档 RedisCommands 1&#xff09;Redis 的命令有上百个&#xff0c;如果纯靠死记硬背比较困难&#xff0c;但是如果理解 Redis 的一些机制&#xff0c;会发现这些命令有很强的通用性。 2&#xff09;Redis 不是万金油&#xff0c;有些数据结构和命令必须在特定场景下使用…

VBA信息获取与处理第五节:如何在单个工作表中查找某个给定值

《VBA信息获取与处理》教程(版权10178984)是我推出第六套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。这部教程给大家讲解的内容有&#xff1a;跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互…

永磁同步电机无速度算法--改进滑模观测器SMO(边界层法)

一、原理介绍 根据滑模观测器的定义&#xff0c;其切换函数是一个拥有高频切换特性的不连续项&#xff0c;为了进一步减小系统的抖振&#xff0c;将符号函数替换为Sigmoid函数&#xff0c;该函数为一种连续、光滑的切换函数&#xff0c;对抖振有良好的抑制效果&#xff0c;其数…

基于SpringBoot+mybatis+layui就业管理系统设计和实现

基于SpringBootmybatislayui就业管理系统设计和实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &…

​《开源高仿Windows 12网页版:零安装体验未来操作系统界面》​​

&#x1f4cc; 大家好&#xff0c;我是智界工具库&#xff0c;致力于分享好用实用且智能的软件以及在JAVA语言开发中遇到的问题&#xff0c;如果本篇文章对你有所帮助请帮我点个小赞小收藏吧&#xff0c;谢谢喲&#xff01;&#x1f618;&#x1f618;&#x1f618; 博主声…

docker 安装达梦数据库(离线)

docker安装达梦数据库&#xff0c;官网上已经下载不了docker版本的了&#xff0c;下面可通过百度网盘下载 通过网盘分享的文件&#xff1a;dm8_20240715_x86_rh6_rq_single.tar.zip 链接: https://pan.baidu.com/s/1_ejcs_bRLZpICf69mPdK2w?pwdszj9 提取码: szj9 上传到服务…