C++迭代器模式
·
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种方法顺序访问聚合对象中的各个元素,而又不暴露该对象的内部表示。这种模式将遍历集合的责任从集合对象中分离出来,交给专门的迭代器对象,从而简化集合的接口和实现。
迭代器模式的核心角色
- 迭代器(Iterator):定义访问和遍历元素的接口
- 具体迭代器(Concrete Iterator):实现迭代器接口,跟踪遍历中的当前位置
- 聚合(Aggregate):定义创建相应迭代器对象的接口
- 具体聚合(Concrete Aggregate):实现创建相应迭代器的接口,返回具体迭代器实例
迭代器模式的实现示例
下面以"自定义集合"为例展示迭代器模式的实现,我们将创建一个支持迭代器的书架集合,用于存储和遍历书籍:
#include <iostream>
#include <string>
#include <vector>
// 前向声明
template <typename T>
class Iterator;
// 聚合接口
template <typename T>
class Aggregate {
public:
virtual Iterator<T>* createIterator() = 0;
virtual int getSize() const = 0;
virtual T getItem(int index) const = 0;
virtual void addItem(const T& item) = 0;
virtual ~Aggregate() = default;
};
// 迭代器接口
template <typename T>
class Iterator {
public:
virtual bool hasNext() const = 0;
virtual T next() = 0;
virtual ~Iterator() = default;
};
// 具体聚合:书架
class Book {
private:
std::string name;
public:
Book(const std::string& bookName) : name(bookName) {}
std::string getName() const { return name; }
};
// 具体聚合:书架
class BookShelf : public Aggregate<Book> {
private:
std::vector<Book> books;
public:
int getSize() const override {
return books.size();
}
Book getItem(int index) const override {
return books[index];
}
void addItem(const Book& item) override {
books.push_back(item);
}
// 创建迭代器
Iterator<Book>* createIterator() override;
};
// 具体迭代器:书架迭代器
class BookShelfIterator : public Iterator<Book> {
private:
const BookShelf* bookShelf;
int index;
public:
BookShelfIterator(const BookShelf* shelf) : bookShelf(shelf), index(0) {}
bool hasNext() const override {
return index < bookShelf->getSize();
}
Book next() override {
Book book = bookShelf->getItem(index);
index++;
return book;
}
};
// 实现BookShelf的createIterator方法
Iterator<Book>* BookShelf::createIterator() {
return new BookShelfIterator(this);
}
// 客户端使用
int main() {
// 创建书架并添加书籍
BookShelf* bookShelf = new BookShelf();
bookShelf->addItem(Book("设计模式"));
bookShelf->addItem(Book("C++ Primer"));
bookShelf->addItem(Book("算法导论"));
bookShelf->addItem(Book("计算机网络"));
// 获取迭代器并遍历
Iterator<Book>* iterator = bookShelf->createIterator();
std::cout << "书架上的书籍:" << std::endl;
while (iterator->hasNext()) {
Book book = iterator->next();
std::cout << "- " << book.getName() << std::endl;
}
// 清理资源
delete iterator;
delete bookShelf;
return 0;
}
迭代器模式的工作原理
- 聚合对象创建一个迭代器对象,迭代器保存了遍历所需的状态(如当前位置)
- 客户端通过迭代器的
hasNext()方法检查是否还有元素 - 客户端通过迭代器的
next()方法获取下一个元素并移动到下一个位置 - 聚合对象不需要暴露其内部结构(如数组、链表等),客户端只需通过迭代器接口访问元素
迭代器的常见类型
- 内部迭代器:由迭代器控制遍历过程,客户端无法干预
- 外部迭代器:由客户端控制遍历过程(如示例中的迭代器)
- 正向迭代器:只能向前遍历(如示例中的迭代器)
- 双向迭代器:可以向前和向后遍历
- 随机访问迭代器:可以直接访问任意位置的元素
迭代器模式与其他模式的关系
- 组合模式:通常结合迭代器模式使用,以便遍历组合对象的树形结构
- 工厂方法模式:聚合对象创建迭代器的过程常用工厂方法模式
迭代器模式的应用场景
- 当需要访问一个聚合对象的元素,而又不想暴露其内部表示时
- 当需要为聚合对象提供多种遍历方式时
- 当需要为不同的聚合结构提供统一的遍历接口时
迭代器模式的优缺点
优点:
- 分离了集合对象的遍历行为,使集合对象更加简洁
- 提供了统一的遍历接口,简化了客户端代码
- 支持多种遍历方式,不同的迭代器可以实现不同的遍历逻辑
- 便于在遍历过程中增加额外操作(如过滤、转换等)
缺点:
- 增加了类的数量,每一种集合可能需要对应一种迭代器
- 对于简单的集合,使用迭代器可能显得过于繁琐
- 在遍历过程中修改集合结构可能会导致迭代器失效
迭代器模式在C++标准库中有着广泛应用,std::vector、std::list等容器都提供了迭代器支持,begin()和end()方法返回迭代器,使客户端可以统一的方式遍历不同的容器。这种设计极大地提高了STL的灵活性和一致性。
更多推荐


所有评论(0)