迭代器模式(C++实现)

(本博客旨在个人总结回顾)

1、详情:

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而有不暴露该对象的内部表示。

说明:

优点: 

①它支持以不同的方式遍历一个聚合对象。

②迭代器简化了聚合类。

③在同一个聚合上可以有多个遍历。

④在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点:

       由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

备注:

迭代器模式的学习意义大于使用意义,因为大部分编程语言都提供了STL(组成:容器、迭代器、算法),而其中的迭代器就是迭代器模式的典型。在我们开发的过程中一般需要使用迭代器模式的情况下都可以直接调用已有的库,所以自己实现迭代器的情况是比较少的。

遇到的问题:

①使用C++模板,编译出错(无法解析外部符号...),

解决方法:

a:将使用模板的类声明和定义都放在一个文件中(例子中的Iterator、Container抽象类,)

b:使用时引用头文件和cpp文件(例子中的IteratorX,ContainerX使用时,#inclued "xx.h"、"xx.cpp")

②两类之间相互调用对方的指针类型:需要在调用前先声明调用的类。

如:

例子中Iterator.h 中的声明:template<class _Item>class Container;

例子中Container.h 中的声明:ttemplate<class _Item>class Iterator; 

2.1、UML类图:

 

2.2、例子源码

stdafx.h

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

#include <iostream>
using namespace std;

// TODO:  在此处引用程序需要的其他头文件

Iterator.h

#pragma once
#include "Container.h"
template<class _Item>class Container;

template<class _Item>
class Iterator
{
public:
    Iterator(Container<_Item>* pContainer, int nIndex)
        : m_pContainer(pContainer)
        , m_nIndex(nIndex)
    {
    }
    virtual ~Iterator(){}

public:
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual _Item* CurrentItem() = 0;
    virtual bool IsEnd() = 0;

protected:
    Container<_Item>* m_pContainer;
    int m_nIndex;
};

IteratorX.h

#pragma once
#include "Iterator.h"
#include "Container.h"

template<class _Item>
class IteratorX :
    public Iterator<_Item>
{
public:
    IteratorX(Container<_Item>* pContainer, int nIndex = 0);
    ~IteratorX();

public:
    void First();
    void Next();
    _Item* CurrentItem();
    bool IsEnd();
};

IteratorX.cpp

#include "stdafx.h"
#include "IteratorX.h"

template<class _Item>
IteratorX<_Item>::IteratorX(Container<_Item>* pContainer, int nIndex)
    : Iterator<_Item>(pContainer, nIndex)
{
}

template<class _Item>
IteratorX<_Item>::~IteratorX()
{
}

template<class _Item>
void IteratorX<_Item>::First()
{
    m_nIndex = 0;
}

template<class _Item>
void IteratorX<_Item>::Next()
{
    m_nIndex++;
}

template<class _Item>
_Item* IteratorX<_Item>::CurrentItem()
{
    if (m_nIndex < m_pContainer->Count())
    {
        return &(*m_pContainer)[m_nIndex];
    }
    return NULL;
}

template<class _Item>
bool IteratorX<_Item>::IsEnd()
{
    return m_nIndex >= m_pContainer->Count();
}

Container.h

#pragma once
#include "Iterator.h"
template<class _Item>class Iterator;

template<class _Item>
class Container
{
public:
    Container() :m_pIterator(NULL){};
    virtual ~Container()
    {
        if (NULL != m_pIterator)
        {
            delete m_pIterator;
            m_pIterator = NULL;
        }
    };

public:
    virtual void AddItem(_Item item) = 0;
    virtual int Count() = 0;
    virtual _Item& operator[](int index) = 0;
    virtual Iterator<_Item>* CreateIterator() = 0;

protected:
    Iterator<_Item>* m_pIterator;
};

ContainerX.h

#pragma once
#include <vector>
#include "Container.h"

template<class _Item>
class ContainerX :
    public Container<_Item>
{
public:
    ContainerX();
    ~ContainerX();

public:
    void                AddItem(_Item item);
    int                 Count();
    _Item&              operator[](int index);
    Iterator<_Item>*    CreateIterator();

private:
    vector<_Item>      m_vectorItems;
};

ContainerX.cpp

#include "stdafx.h"
#include "ContainerX.h"

template<class _Item>
ContainerX<_Item>::ContainerX() 
    : Container<_Item>()
{
}

template<class _Item>
ContainerX<_Item>::~ContainerX()
{
}

template<class _Item>
void ContainerX<_Item>::AddItem(_Item item)
{
    m_vectorItems.push_back(item);
}

template<class _Item>
int ContainerX<_Item>::Count()
{
    return m_vectorItems.size();
}

template<class _Item>
_Item& ContainerX<_Item>::operator[](int index)
{
    return m_vectorItems[index];
}

template<class _Item>
Iterator<_Item>* ContainerX<_Item>::CreateIterator()
{
    if (m_pIterator == NULL)
    {
        m_pIterator = new IteratorX<_Item>(this);
    }
    return m_pIterator;
}

调用代码

IteratorPatternMemo.cpp

// IteratorPatternMemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <list>
#include "IteratorX.h"
#include "IteratorX.cpp"
#include "ContainerX.h"
#include "ContainerX.cpp"

int _tmain(int argc, _TCHAR* argv[])
{
    Container<string>* pContainer = new ContainerX<string>();
    pContainer->AddItem("dog");
    pContainer->AddItem("cat");
    pContainer->AddItem("pig");

    
    Iterator<string>* it = pContainer->CreateIterator();
    cout << "变量容器item:" << endl;
    for (it->First(); !it->IsEnd(); it->Next())
    {
        cout << (*(it->CurrentItem())).c_str() << endl;
    }

    system("pause");
	return 0;
}

2.3、运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值