对聚合类(如列表)的访问和遍历从列表对象中分离出来,并放入一个迭代器对象中
迭代器定义了一个访问该列表元素的接口,迭代器负责跟踪当前的元素,即知道哪些元素已经遍历过了,如下图所示:
Iterator:定义迭代器访问和遍历元素的接口;
ConcreteIterator:实现具体的迭代器;
Aggregate:定义的容器,创建相应迭代器对象的接口;
ConcreteAggregate:具体的容器实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
然后Aggregate中加入Iterator的对象这样就可以访问容器的方法了实现遍历。
实现要点:
1.迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。
2.迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
3.迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。
适用性:
1.访问一个聚合对象的内容而无需暴露它的内部表示。
2.支持对聚合对象的多种遍历。
3.为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
一个简单的实现:
#include"stdafx.h"
#include<string>
#include <iostream>
#include <vector>
template <typename Item>
class SongsBook;
/*** 迭代器类声明定义 ***/
template <typename Item>
class Iterator
{
public:
virtual Item* first() = 0;
virtual Item* next() = 0;
//virtual void toTop(Item* ) = 0;
virtual Item* currentItem() = 0;
virtual bool isDone() = 0;
virtual ~Iterator() {};
};
template <typename Item>
class KtvCrlor : public Iterator<Item>
{
public:
KtvCrlor(SongsBook<Item>* songsbook) : songsbook(songsbook), index(0) { }
virtual Item* first();
virtual Item* next();
virtual Item* currentItem();
virtual bool isDone();
private:
SongsBook<Item>* songsbook;
int index;
};
// --- 成员函数实现 ---
template <typename Item>
Item* KtvCrlor<Item>::first()
{
index = 0;
return (*songsbook)[0];
}
template <typename Item>
Item* KtvCrlor<Item>::next()
{
return (*songsbook)[index++];
}
template<typename Item>
Item* KtvCrlor<Item>::currentItem()
{
return (*songsbook)[index];
}
template <typename Item>
bool KtvCrlor<Item>::isDone(){
return (index >= songsbook->count());
}
/*** 聚类声明定义 ***/
template<typename Item>
class Aggregate
{
public:
Aggregate<Item>() {};
virtual Iterator<Item>* createIterator() = 0;
virtual ~Aggregate() {};
};
template<typename Item>
class SongsBook : public Aggregate<Item>
{
public:
SongsBook<Item>() : Aggregate<Item>() { };
void addSong(Item* song);
int count();
virtual Iterator<Item>* createIterator();
Item* operator[](int index);
private:
std::vector<Item*> songs;
};
// --- 成员函数实现 ---
template<typename Item>
int SongsBook<Item>::count() {
return songs.size();
}
template<typename Item>
void SongsBook<Item>::addSong(Item* song) {
if (song != NULL)
songs.push_back(song);
std::cout << "添加歌曲: " << *song << std::endl;
}
template<typename Item>
Iterator<Item>* SongsBook<Item>::createIterator()
{
return new KtvCrlor<Item>(this);
}
template<typename Item>
Item* SongsBook<Item>::operator[](int index) {
return songs[index];
}
int main()
{
SongsBook<std::string>* songsbook = new SongsBook<std::string>();
Iterator<std::string>* ktvController = songsbook->createIterator();
/* 选中歌曲 */
std::cout << "请选择歌曲" << std::endl;
songsbook->addSong(new std::string("春天里"));
songsbook->addSong(new std::string("生如夏花"));
songsbook->addSong(new std::string("我是一棵秋天的树 "));
songsbook->addSong(new std::string("冬天里的一把火"));
/* 遍历曲库 */
std::cout << std::endl;
std::cout << "当前列表中包含歌曲: " << songsbook->count() << "首" << std::endl;
while (!ktvController->isDone()) {
std::cout << *ktvController->next() << std::endl;
}
system("Pause");
}