组合模式通过Component抽象接口统一处理Leaf和Composite,使客户端无需区分节点类型即可一致操作树形结构;核心是用std::unique_ptr管理内存、基类提供默认异常抛出,并避免循环引用。
组合模式(Composite Pattern)在 C++ 中用于统一处理单个对象(Leaf)和复合对象(Composite),让客户端可以一致地操作整个树形结构。核心是定义一个公共接口,让叶子节点和容器节点都实现它,从而屏蔽结构差异。
组合模式有三个关键角色:
add、remove、operation),提供默认空实现或纯虚函数;add)可抛异常或忽略;std::vector<:unique_ptr>> 等子节点集合,转发操作到子节点,并支持动态增删。模拟“文件(File)”和“目录(Directory)”,二者都可调用 display(),目录还能添加子项:
class Component {
public:
virtual ~Component() = default;
virtual void display(int indent = 0) const = 0;
virtual void add(std::unique_ptr) {
throw std::runtime_error("add not supported for this component");
}
virtual void remove(const std::string&) {
throw std::runtime_error("remove not supported for this component");
}
};
// Leaf: File.hclass File : public Component {
std::string name_;
public:
explicit File(std::string n) : name_(std::move(n)) {}
void display(int indent) const override {
std::cout << std::string(indent, ' ') << "? " << name_ << '\n';
}
};
// Composite: Directory.hclass Directory : public Component {
std::string name_;
std::vector> children_;
public:
explicit Directory(std::string n) : name_(std::move(n)) {}
void display(int indent) const override {
std::cout << std::string(indent, ' ') << "? " << name_ << '\n';
for (const auto& child : children_) {
child->display(indent + 2);
}
}
void add(std::unique_ptr child) override {
children_.push_back(std::move(child));
}
void remove(const std::string& targetName) override {
children_.erase(
std::remove_if(children_.begin(), children_.end(),
[&targetName](const auto& c) -> bool {
// 简单匹配(实际可用 dynamic_cast 或 typeid 判断)
return c && c->getName() == targetName;
}),
children_.end()
);
}
// 辅助:为演示加一个 getName(实际中可用 visitor 或其他方式解耦)
virtual std::string getName() const { return name_; }
};
客户端代码无需区分叶子或容器,统一调用 display():
int main() {
auto root = std::make_unique("root");
root->add(std::make_unique("readme.md"));
auto src = std::make_unique("src");
src->add(std::make_unique("main.cpp"));
src->add(std::make_unique("utils.h"));
auto test = std::make_unique("test");
test->add(std::make_unique("test_main.cpp"));
root->add(std::move(src));
root->add(std::move(test));
root->display(); // 递归输出整棵树
}
输出效果:
? root
? readme.md
? src
? main.cpp
? utils.h
? test
? test_main.cpp
std::unique_ptr 管理子节点,避免裸指针和资源泄漏;add/remove,但保留接口——由基类提供默认异常抛出,比返回错误码更符合 C++ 惯例;不复杂但容易忽略:组合模式的价值不在“能写出来”,而在于它把“是否为容器”的判断从客户端逻辑中彻底剥离——只要面向 Component 编程,树有多深、混合多杂,都不影响调用方式。
# ai
# c++
# 子类
# Directory
# 循环
# 指针
# 虚函数
# 纯虚函数
# 接口
# 堆
# 对象
# display
# 客户端
# 遍历
# 递归
# 抛出
# 都不
# 还能
# 不应
# 而非
# 文件系统
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
c++中explicit(bool)的用法 c++条件性explicit【C++20】
php文件怎么变mp4保存_php输出视频流保存为mp4操作【操作】
c++中如何使用auto关键字_c++11类型推导用法说明
Win11怎么关闭应用权限_Windows11相机麦克风隐私管理
Win10怎么卸载鲁大师_Win10彻底卸载鲁大师方法【步骤】
Python lxml的etree和ElementTree有什么区别
Win11怎么关闭防火墙通知_屏蔽Win11安全中心安全警告弹窗【技巧】
Windows10如何更改盘符名称_Win10重命名硬盘分区卷标
Mac如何创建和管理多个桌面空间_Mac高效多任务处理【技巧】
短链接怎么自定义还原php_修改解码规则适配需求【汇总】
Win10怎样安装Excel数据分析工具_Win10安装分析工具包步骤【教程】
php中self::能调用子类重写的方法吗_静态绑定与重写关系【介绍】
静态属性修改会影响所有实例吗_php作用域操作符下静态存储【教程】
如何使用Golang log设置日志输出格式_Golang log日志格式示例
C++如何使用std::transform批量处理容器元素?(代码示例)
Win10怎样设置多显示器_Win10多显示器扩展设置【攻略】
win11如何清理传递优化文件 Win11为C盘瘦身删除更新缓存【技巧】
Win11怎么查看已连接wifi密码 Win11查已连wifi密码步骤【教程】
Go 语言标准库为何不提供泛型切片的 Contains 方法?
Mac如何设置动态壁纸?(让桌面动起来)
Python与MongoDB NoSQL开发实战_文档模型与索引优化
用Python构建微服务架构实践_FastAPI与Django对比详解
php中::能用于接口静态方法吗_接口静态方法调用规则【操作】
如何使用正则表达式批量替换重复的“-”模式为固定字符串
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
TestNG的testng.xml配置文件怎么写
Windows10系统怎么查看显卡型号_Win10 dxdiag显示选项卡
如何将文本文件中的竖排字符串转换为横排字符串
c++ std::atomic如何保证原子性 c++ CAS操作原理【底层】
php怎么下载安装后设置错误日志_phpini log配置教程【汇总】
如何在 IIS 上为 ASP.NET 6 应用排除特定目录并交由 PHP 处理
如何在JavaScript中动态拼接PHP的base_url与jQuery变量
如何在Golang中实现RPC异步返回_Golang RPC异步处理与回调方法
Win11怎么关闭触摸键盘图标_Windows11任务栏系统托盘设置
Win11如何设置开机自动联网 Win11宽带连接自动拨号【步骤】
Win11怎么设置快速访问_Windows11文件资源管理器主页
Win11怎么设置默认PDF阅读器 Win11修改PDF打开方式【步骤】
php中$this和::能混用吗_对象与静态作用域冲突解决【方法】
Win10如何更改电脑休眠时间_Windows10电源和睡眠选项调整
Drupal 中 HTML 链接被双重转义导致渲染异常的解决方案
C++中引用和指针有什么区别?(代码说明)
Windows 10怎么隐藏特定更新补丁_Windows 10使用微软官方工具wushowhide.diagcab
如何使用Golang reflect检查方法数量_动态分析类型方法
Windows10电脑怎么设置虚拟内存_Win10高级系统设置性能
Win11怎么更改电脑密码_Windows 11修改本地账户密码【步骤】
Win11键盘快捷键大全_Windows 11常用高效快捷键汇总【技巧】
如何高效删除 NumPy 二维数组中所有元素相同的列
如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法
Python日志系统设计与实现_高可观测性架构实战
Win11怎么更改盘符_Win11磁盘管理修改驱动器号【步骤】
2025-12-25
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。