【设计模式】迭代器模式

Posted by 卢小胖 on 2023-09-11
Estimated Reading Time 3 Minutes
Words 654 In Total
Viewed Times

什么是迭代器

通过迭代器可以顺序访问容器内的数据

迭代器模式

迭代器是一种行为设计模式, 让你能在不暴露复杂数据结构内部细节的情况下遍历其中所有的元素。

迭代器使用场景

  • 统一容器类的遍历方式
  • 在不暴露原有数据下,使用不同的方式来遍历整个整合对象
  • 使用迭代器模式在新增容器类的时候,修改更加方便。

缺点:

  • 增加类的设计复杂度

具体实现

为了考虑到多类复用,我们直接上模板

1、Iterator.h

Iterator中的方法:

  • first() //迭代器置为容器第一个数据
  • end() //迭代器置为容器最后一个数据
  • next() //迭代器顺序推进
  • curItem() //迭代器当前地址
  • isDone() //判断迭代器是否遍历完成
#ifndef CPPDESIGNMODE_MYITERATOR_H
#define CPPDESIGNMODE_MYITERATOR_H

#include <vector>
#include <iterator>

//迭代器
//Item指的是原始数据类型,Container是容器类型。
template<typename Item,typename Container>
class MyIterator
{
public:
//关键字 typename 来显示的说明它是一个类型而非 成员变量。否则编译会报错
typedef typename std::vector<Item>::iterator iter_type;

explicit MyIterator(Container* c_data) : m_c_data(c_data)
{
it = m_c_data->data.begin();
};

virtual ~MyIterator()
{
std::cout << "MyIterator deleted!!" << std::endl;
};

void first()
{
it = m_c_data->data.begin();
}

void next()
{
it++;
}

void end()
{
it = m_c_data->data.end();
}


iter_type curItem()
{
return it;
}

bool isDone()
{
return it == m_c_data->data.end();
}

private:
Container* m_c_data;
iter_type it;
};

#endif //CPPDESIGNMODE_MYITERATOR_H


2、容器类Aggregate.h

容器类的设计也很简单:

  • 使用vector保存原始数据
  • 设置友元类,让MyIterator能获取到原始数据
  • 注意创建MyIterator指针的时候传入的泛型类型。
#pragma once
#include "vector"
#include "MyIterator.h"

//迭代器容器抽象类
template<typename Item>
class Aggregate{

//声明友元类是为了解决MyIterator无法访问原始容器
friend class MyIterator<Item,Aggregate>;

public:
Aggregate(){};

virtual ~Aggregate()
{
data.clear();
data.shrink_to_fit();
std::cout << "Deleted Aggregate!!" << std::endl;
};

void push(Item item)
{
data.push_back(item);
};

MyIterator<Item,Aggregate>* createIterator()
{
return new MyIterator<Item,Aggregate>(this);
};

Item& operator[](int index)
{
return data[index];
};

int size()
{
return data.size();
};

private:
std::vector<Item> data;
};

3、具体示例

#include <iostream>
#include "Aggregate.h"

int main() {

Aggregate<int> *aggregate = new Aggregate<int>();
aggregate->push(1);
aggregate->push(3);
aggregate->push(5);

MyIterator<int,Aggregate<int>>* iterator = aggregate->createIterator();

for (iterator->first(); !iterator->isDone(); iterator->next()) {
std::cout << *iterator->curItem() << std::endl;
}

delete iterator;
delete aggregate;

return 0;
}

输出:

1
3
5
MyIterator deleted!!
Deleted Aggregate!!