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

组合模式(Composite Pattern)允许将对象组合成树形结构,使得客户端以统一的方式处理单个对象和组合对象。以下是一个经典的 C++ 实现示例,包含透明式设计(基类定义统一接口)和内存管理:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <memory>

// 抽象组件类
class Component {
public:
    virtual ~Component() = default;
    virtual void operation() const = 0;
    
    // 管理子组件的透明接口(Leaf需处理不支持的操作)
    virtual void add(std::unique_ptr<Component> component) {
        throw std::runtime_error("Unsupported operation: add");
    }
    virtual void remove(Component* component) {
        throw std::runtime_error("Unsupported operation: remove");
    }
    virtual const Component* getChild(int index) const {
        throw std::runtime_error("Unsupported operation: getChild");
    }
};

// 叶子节点类
class Leaf : public Component {
public:
    explicit Leaf(std::string name) : name_(std::move(name)) {}
    
    void operation() const override {
        std::cout << "Leaf[" << name_ << "] 执行操作" << std::endl;
    }
    
private:
    std::string name_;
};

// 组合节点类
class Composite : public Component {
public:
    void operation() const override {
        std::cout << "Composite 执行操作,包含" << children_.size() << "个子组件:" << std::endl;
        for (const auto& child : children_) {
            child->operation(); // 递归调用子组件的操作
        }
    }
    
    void add(std::unique_ptr<Component> component) override {
        children_.push_back(std::move(component));
    }
    
    void remove(Component* component) override {
        auto it = std::find_if(children_.begin(), children_.end(),
            [component](const std::unique_ptr<Component>& c) {
                return c.get() == component;
            });
        if (it != children_.end()) {
            children_.erase(it);
        }
    }
    
    const Component* getChild(int index) const override {
        if (index >= 0 && index < children_.size()) {
            return children_[index].get();
        }
        return nullptr;
    }

private:
    std::vector<std::unique_ptr<Component>> children_; // 使用智能指针管理生命周期
};

// 客户端代码
int main() {
    // 创建组合结构:root -> [branch1, branch2]
    // branch1 -> [leaf1, leaf2]
    // branch2 -> [leaf3]
    auto root = std::make_unique<Composite>();
    
    auto branch1 = std::make_unique<Composite>();
    branch1->add(std::make_unique<Leaf>("A"));
    branch1->add(std::make_unique<Leaf>("B"));
    
    auto branch2 = std::make_unique<Composite>();
    branch2->add(std::make_unique<Leaf>("C"));
    
    root->add(std::move(branch1));
    root->add(std::move(branch2));
    
    // 统一调用操作
    root->operation();
    
    return 0;
}

关键点解析:

  1. 透明式设计:

    • Component 基类定义了所有组件(包括叶子节点)的公共接口,包括 add/remove 等管理子组件的方法。
    • 叶子节点 Leaf 继承自 Component,但重写 add/remove 时抛出异常(代码中省略异常以简化,实际可添加)。
    • 组合节点 Composite 实现子组件管理逻辑,并递归调用子组件的 operation()。
  2. 内存管理:

    • 使用 std::unique_ptr 管理子组件生命周期,确保组合对象析构时自动释放所有子组件。
    • 避免手动 new/delete,减少内存泄漏风险。
  3. 递归结构:

    • Composite 的 operation() 会遍历所有子组件并调用它们的操作,形成递归处理。

输出结果:

复制代码
Composite 执行操作,包含2个子组件:
Composite 执行操作,包含2个子组件:
Leaf[A] 执行操作
Leaf[B] 执行操作
Composite 执行操作,包含1个子组件:
Leaf[C] 执行操作

此实现展示了组合模式的核心思想:客户端无需区分叶子节点和组合节点 ,统一通过 Component 接口操作,简化了复杂树形结构的处理。

相关推荐
无名猿11 分钟前
构造函数详解:默认、委托、转换与 explicit 到底写在哪
c++·现代c++·语法基础
纪念 22924 分钟前
C++ string(一)
android·开发语言·c++
纪念 22926 分钟前
C++算法(二)
开发语言·c++·算法
AC赳赳老秦9 小时前
采集行为合规自检:OpenClaw 自动校验 robots 协议与采集频率,规避违规采集风险
java·开发语言·c++·python·php·deepseek·openclaw
无名猿9 小时前
C++ 查找算法:std::find 与容器成员 find 的性能差距
c++·性能优化·stl·标准库
程序猿编码10 小时前
工业视觉多任务方案:可编程梯度信息视觉框架,训练评估 + C++ 部署完整实战
开发语言·c++·视觉·推理引擎
朝朝辞暮i11 小时前
C++ 第 21 课:struct —— 把一组相关数据打包在一起
开发语言·c++·算法
SHARK_pssm12 小时前
【C++——类和对象(下)】
开发语言·c++·经验分享·笔记
汉克老师13 小时前
GESP2026年9月认证C++二级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
沫璃染墨13 小时前
《从零入门Linux系统篇(五十四):线程篇·七——互斥锁底层原理:从原子交换到线程竞争与锁实现》
linux·运维·服务器·开发语言·c++·驱动开发·系统架构