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. 递归结构

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

输出结果:

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

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

相关推荐
️停云️24 分钟前
【滑动窗口与双指针】不定长滑动窗口
c++·算法·leetcode·剪枝·哈希
charlie11451419127 分钟前
嵌入式现代C++教程: 构造函数优化:初始化列表 vs 成员赋值
开发语言·c++·笔记·学习·嵌入式·现代c++
IT=>小脑虎1 小时前
C++零基础衔接进阶知识点【详解版】
开发语言·c++·学习
码农小韩1 小时前
基于Linux的C++学习——指针
linux·开发语言·c++·学习·算法
小L~~~1 小时前
绿盟校招C++研发工程师一面复盘
c++·面试
微露清风1 小时前
系统性学习C++-第十九讲-unordered_map 和 unordered_set 的使用
开发语言·c++·学习
_Lzk666888_2 小时前
洛谷用户2002780求关注
c++·其他
无限进步_3 小时前
【C语言&数据结构】对称二叉树:镜像世界的递归探索
c语言·开发语言·数据结构·c++·git·算法·visual studio
X***07883 小时前
C语言在嵌入式系统开发中的应用与挑战
c++
小芒果_013 小时前
整理归并排序
c++·算法·排序算法·信息学奥赛