前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++设计模式 - 迭代器模式

C++设计模式 - 迭代器模式

作者头像
开源519
发布2022-12-01 16:08:13
4320
发布2022-12-01 16:08:13
举报
文章被收录于专栏:开源519开源519

前言

你的坚持,终将美好!

迭代器模式

❝提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 ❞

C++ STL中各个容器都有迭代器的体现,通过迭代器能够顺序的访问该容器各成员。

意义

有利于隐藏聚合类的内部实现,外部通过迭代器来实现对聚合类的顺序访问。

场景

实现聚合类的一种顺序访问。

注: 对于开发者来讲,基本上不会实现一套迭代器。因为现存的标准库都有提供各种容器List、Array等,都有提供迭代器遍历。这里只是简单分析这种模式的实现原理。

类图

迭代器模式类图

  • CIteratorBase: 迭代器基类。定义访问容器常用操作的接口。
  • CIterator: 具体迭代器类。负责实现访问容器常用操作的接口。
  • CAggregateBase: 聚合基类。表示具体的容器基类。
  • CAggregate: 具体聚合类。

注: 为了实现通用的迭代器,迭代器类使用了泛型编程的模板方法。

源码实现

「编程环境」

  1. 编译环境: Linux环境
  2. 语言: C++语言
  3. 编译命令: make

「工程结构」

代码语言:javascript
复制
Iterator/
├── aggregatebase.h
├── aggregate.h
├── iteratorbase.h
├── iterator.h
├── main.cc
└── Makefile
  • iterator*: 迭代器实现代码
  • aggregate*: 聚合类实现代码
  • main.cc: 客户端代码,程序入口
  • Makefile: 编译工具

「迭代器实现」

代码语言:javascript
复制
template<typename T>
class CIterator : public CIteratorBase <T>
{
public:
    CIterator(CAggregate<T>* aggregate) : mIndex(0), mAgg(aggregate)
    {

    }

    ~CIterator()
    {
        if (NULL != mAgg) {
            delete mAgg;
        }
    }

    T* First()
    {
        mIndex = 0;
        if (mAgg->mData[0]) {
            return &mAgg->mData[0];
        } else {
            ITER_LOGE("mAgg is NULL!\n");
            return NULL;
        }
    }

    T* Next()
    {
        mIndex++;
        if (mIndex < mAgg->mData.size()) {
            return &mAgg->mData[mIndex];
        } else {
            ITER_LOGD("mAgg is NULL!\n");
            return NULL;
        }
    }

    T *CurPos()
    {
        if (mAgg->mData[mIndex]) {
            return &mAgg->mData[mIndex];
        } else {
            ITER_LOGE("mAgg is NULL!\n");
            return NULL;
        }
    }

    bool IsEnd()
    {
        if (mIndex < mAgg->mData.size()) {
            return true;
        } else {
            ITER_LOGD("mIndex[%d] Size[%ld]\n", mIndex, mAgg->mData.size());
            return false;
        }
    }

private:
    unsigned int mIndex;
    CAggregate<T> *mAgg;
};
  • 这里使用了泛型编程模板方式,适配各种类型聚合类的顺序访问。
  • 由于模板方式声明与实现不能分离,这里将两者都放在头文件,不利于实现的隐藏且不美观。如有更好的方式,可以后台告知,谢谢。

「聚合类实现」

代码语言:javascript
复制
template <typename T>
class CAggregate : public CAggregateBase<T>
{
    friend class CIterator <T>;

public:
    CAggregate() : mIterator(NULL)
    {

    }

    ~CAggregate()
    {
        if (mIterator) {
            delete mIterator;
        }
    }

    void push_back(T data)
    {
        mData.push_back(data);
    }

private:
    std::vector<T> mData;
    CIteratorBase<T>* mIterator;
};
  • 同样的聚合类为了适配各类型,同样采用了泛型编程的模板方式。可把此类看成类似STL中的vector、List的容器类。其内部可存储同一类型的多个元素。
  • 此容器持有一个迭代器成员,外部可以通过此迭代器来访问容器中的各个元素。
  • 由于本设计迭代器需要访问聚合类私有的成员,因此将CIterator定义为友元,为了避免重复引用,前置声明CIterator。

「客户端代码」 测试内容大致为: 定义了一个容器,依次向容器中存放变量,并遍历。

  1. int型容器
代码语言:javascript
复制
int main(int argc, char *argv[])
{
    int i = 0;
    CAggregate<int> *agg = new CAggregate<int>();
    CIterator<int> it(agg);

    agg->push_back(1);
    agg->push_back(2);
    agg->push_back(13);

    for (it.First(); it.IsEnd(); it.Next())
    {
        printf("[%d]: %d\n", i, *it.CurPos());
        i++;
    }

    return 0;
}
  1. float容器
代码语言:javascript
复制
int main(int argc, char *argv[])
{
    int i = 0;
    CAggregate<float> *agg = new CAggregate<float>();
    CIterator<float> it(agg);

    agg->push_back(1.2);
    agg->push_back(2);
    agg->push_back(13);

    for (it.First(); it.IsEnd(); it.Next())
    {
        printf("[%d]: %0.2f\n", i, *it.CurPos());
        i++;
    }

    return 0;
}

测试效果

  1. int型:
代码语言:javascript
复制
$ ./exe 
[0]: 1
[1]: 2
[2]: 13

2: float型:

代码语言:javascript
复制
./exe 
[0]: 1.20
[1]: 2.00
[2]: 13.00

通过测试发现,两种类型的容器都可以实现遍历。

总结

  • 单一职责原则。通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
  • 开闭原则。可以实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
  • 可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态。
  • 在C++ STL库中已经提供迭代器的实现。本文的实现主要是了解迭代器的大致原理。

最后

用心感悟,认真记录,写好每一篇文章,分享每一框干货。

更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入“开源519公众号”聊天界面输入“文章目录” 或者 菜单栏选择“文章目录”查看。公众号后台聊天框输入本文标题,在线查看源码。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 迭代器模式
    • 意义
      • 场景
        • 类图
          • 源码实现
            • 测试效果
              • 总结
                • 最后
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档