如何在C++中为抽象类Aggregate定义迭代器以遍历Primitive?
关于C++ Aggregate容器遍历的实现方案
1. 这样的操作是否可行?
完全可行。这本质上是迭代器模式的典型应用——通过抽象迭代器接口,让调用者无需关心容器内部的存储结构(比如用vector、list还是自定义结构存储Primitive对象),就能以统一的方式遍历容器内的元素。
2. Aggregate类及其派生类需要实现的内容
核心思路是为Aggregate抽象类定义统一的迭代器接口,派生类根据自身的存储方式实现具体的迭代器逻辑。具体实现步骤如下:
步骤1:定义抽象迭代器类
先封装一个抽象迭代器类,提供遍历Primitive对象的基础操作:
class PrimitiveIterator { public: virtual ~PrimitiveIterator() = default; // 获取当前指向的Primitive对象(返回指针/引用可根据需求调整) virtual Primitive* current() const = 0; // 移动到下一个元素 virtual void next() = 0; // 判断遍历是否结束 virtual bool isDone() const = 0; // 重置迭代器到起始位置 virtual void reset() = 0; };
步骤2:在Aggregate抽象类中定义迭代器创建接口
Aggregate作为抽象容器,需要提供纯虚函数让派生类返回对应的具体迭代器实例:
class Aggregate { public: virtual ~Aggregate() = default; // 返回智能指针避免手动管理内存 virtual std::unique_ptr<PrimitiveIterator> createIterator() const = 0; };
步骤3:派生类实现存储结构与具体迭代器
以用std::vector存储Primitive的ConcreteAggregate为例,实现对应的具体迭代器:
// 绑定到ConcreteAggregate存储结构的具体迭代器 class ConcreteIterator : public PrimitiveIterator { private: const ConcreteAggregate& m_aggregate; size_t m_index = 0; public: explicit ConcreteIterator(const ConcreteAggregate& agg) : m_aggregate(agg) {} Primitive* current() const override { return m_index < m_aggregate.m_elements.size() ? m_aggregate.m_elements[m_index].get() : nullptr; } void next() override { if (m_index < m_aggregate.m_elements.size()) ++m_index; } bool isDone() const override { return m_index >= m_aggregate.m_elements.size(); } void reset() override { m_index = 0; } }; // 具体的Aggregate派生类 class ConcreteAggregate : public Aggregate { private: std::vector<std::unique_ptr<Primitive>> m_elements; public: void addPrimitive(std::unique_ptr<Primitive> primitive) { m_elements.push_back(std::move(primitive)); } std::unique_ptr<PrimitiveIterator> createIterator() const override { return std::make_unique<ConcreteIterator>(*this); } // 让迭代器能访问内部存储,声明为友元 friend class ConcreteIterator; };
步骤4:统一遍历逻辑
调用者无需关心ConcreteAggregate的存储细节,直接通过Aggregate接口遍历:
void traverse(const Aggregate& agg) { auto iter = agg.createIterator(); for (; !iter->isDone(); iter->next()) { if (Primitive* prim = iter->current()) { // 调用Primitive的业务方法,比如prim->process(); } } }
额外优化建议
如果使用C++11及以上标准,也可以让Aggregate派生类实现begin()和end()方法,返回符合标准库要求的迭代器(比如封装std::vector的迭代器),这样就能直接用范围for循环遍历:
// 在ConcreteAggregate中添加 auto begin() const { return m_elements.begin(); } auto end() const { return m_elements.end(); } // 遍历代码简化为 for (const auto& prim : concreteAgg) { prim->process(); }
内容的提问来源于stack exchange,提问作者melosomelo
相关产品推荐
相关产品推荐

