首页 > 代码库 > Iterator - 迭代器模式
Iterator - 迭代器模式
定义
提供一个方法顺序访问一个聚合对象中个各个元素,而又不需要暴露该对象的内部结构。
案例
一个聚合对象,如一个列表List,应该提供一种方法来让别人可以访问它的元素,而又不用暴露内部结构。迭代器模式可以很好的解决这类问题,关键思想就是将队列表的访问和遍历从列表对象中分离出来,放到一个迭代器Iterator对象中,Iterator定义了一个访问List对象的接口。
AbstractList提供了List的基本接口:
template<class Item>
class AbstractList {
public:
virtual Iterator* createIterator() const = 0;
virtual int count() const = 0;
virtual void append(Item item) = 0;
virtual void remove(Item item) = 0;
virtual void get(Int index) = 0;
};
在其子类中实现相关操作:
template<class Item>
class ListOne : public AbstractList {
public:
virtual Iterator* createIterator() const;
...
};
Iterator* ListOne::createIterator() {
return new IteratorOne<Item>(this);
}
Iterator类提供公有接口来支持迭代:
template<class Item>
class Iterator {
public:
virtual void first() = 0;
virtual void next() = 0;
virtual bool isEnd() const = 0;
virtual Item current() const = 0;
proteced:
Iterator();
};
子类进行具体操作的实现:
template<class Item>
class IteratorOne : public Iterator {
public:
IteratorOne(const ListOne<Item>* list);
virtual void first();
virtual void next();
virtual bool isEnd() const;
virtual Item current() const;
private:
ListOne<Item>* m_list;
int m_index;
};
template<class Item>
void IteratorOne::first() {
m_index = 0;
}
template<class Item>
void IteratorOne::next() {
++m_index;
}
template<class Item>
bool IteratorOne::isEnd() const {
return m_index == m_list->count();
}
tempalte<class Item>
Item IteratorOne::current() const {
if(isEnd())
throw IteratorOutOfBounds();
return m_list->get(m_index);
}
比如现在我们要打印Book类的一个List的书名:
ListOne<Book*> books;
IteratorOne<Book*>* iter = books.createIterator();
for(iter->first(); !iter->isEnd(); iter->next()) {
std::cout << iter->current()->print();
}
delete iter;
这样实现必须保证每次迭代器都被删除,可以定义一个IteratorPtr来确保对象被释放:
template<class Item>
class IteratorPtr {
public:
IteratorPtr(Iterator<Item>* iter) : m_iter(iter) {}
~IteratorPtr() { delete m_iter; }
Iterator<Item>* operator->() { returm m_iter; }
Iterator<Item>* operator*() { return *m_iter; }
private:
Iterator<Item>* m_iter;
}
ListOne<Book*> books;
IteratorPtr<Book*> iter(books.createIterator());
for(iter->first(); !iter->isEnd(); iter->next()) {
std::cout << iter->current()->print();
}
以上是迭代器的一种外部实现方式,还有一种内部实现方式:
template<class Item>
class ListTraverser {
public:
ListTravrerser(ListOne<Item>* list);
void traverse();
proteced:
virtual void processItem(const Item&) = 0;
private:
IteratorOne<Item> m_iter;
};
void ListTraverser::traverse() {
bool result = false;
for(m_iter.first(); !m_iter.isEnd(); m_iter.next()) {
processItem(m_item.current());
}
}
如果是Book对象的迭代操作,就可以定义一个BookTraverser类,实现processItem函数:
void BookTraverse::processItem(const Book* book) {
cout << book;
}
List<Book> books;
BookTraverse bt(books);
bt.traverse();
适用性
- 访问一个集合对象的内容而无需要暴露它的内部展示
- 支持对集合对象的多种遍历
- 为遍历不同的集合结构提供一个统一的接口
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。