零、前言
最近几天,真的是和迭代器干上了.......
这篇博客,通过简单实现vector中的迭代器,了解迭代器的机制
一、迭代器的设计思想:
为什么要有迭代器?
答:迭代器模式(Iterator ):提供一种方法顺序访问聚合对象中的每个元素,而不是暴露其内部表示。
要访问容器对象就要涉及要遍历算法,我们可以将遍历算法封装在容器中,但是这样的话容器类就承担了太多的功能,容器不仅要维护自身的数据元素还要对外提供遍历的接口方法;如果不提供遍历方法而让使用者自己去实现,又会让容器内不细节暴露。
这个矛盾一提出,首先想到的话就是《程序员的自我修养》中说的:“计算机中的任何问题都可以通过增加一个中间层来解决。
。”感觉这也是我在学习过程中经常用到的解决方法。迭代器模式应运而生:在客户访问类 和 容器之间加入中间层:迭代器。
UML类图:
三、写代码:
Vector的设计:
1.构造
2.扩容
3.迭代器的
template<typename T>
class Vector
{
private:
bool full()
{
return cursize == totalsize;
}
T* parr; //数组的指针
int cursize;//当前元素个数 :也可以当做当前容器中最后一个元素的后一个元素下标,用于插入操作
int totalsize;//当前vector总大小
public:
typedef Iterator<T> iterator;
Vector()
{
parr = new T[2]();
cursize = 0;
totalsize = 2;
}
iterator begin()
{
return iterator(this, 0);
}
iterator end()
{
return iterator(this, cursize);
}
void push_back(T data)
{
insert(end(), data);
}
void insert(iterator _where, T data)
{
if (full())
{
resize();
}
for (iterator it = end(); it != _where; it--)
{
*it = *(it - 1);
}
*_where = data;
cursize++;
}
~Vector()
{
delete[] parr;
parr = NULL;
}
void resize()
{
T* pnewspace = new T[totalsize * 2];
memcpy(pnewspace, parr, sizeof(T)*totalsize);
delete[] parr;
parr = pnewspace;
totalsize *= 2;
}
void Show()
{
for (int i = 0; i < cursize; i++)
{
std::cout << parr[i] << " ";
}
std::cout << std::endl;
}
//arr[0] = 10;
T& operator[](int index)
{
return parr[index];
}
};
迭代器的设计:
思考迭代器要写那些函数?那些成员?
template<typename T>
class Vector;
template<typename T>
class Iterator
{
private:
Vector<T>* pvec; //迭代器的一种说法:对象的指针,即vector对象的指针
int index; //因为遍历vector用下标就可以
public:
//这里构造一个迭代器,用一个对vector象的指针,和 vector对象的下标,下标可以确定要具体的那个
Iterator(Vector<T>* pv, int idx) :
pvec(pv), index(idx)
{}
//重载!= ++ -- *等等,因为迭代器的使用中要使用大量的运算符
bool operator!=(const Iterator left)
{
return index != left.index;
}
T& operator*()const;
const Iterator operator++(int)
{
const Iterator tmp(*this);
index++;
return tmp;
}
const Iterator operator--(int)
{
const Iterator tmp(*this);
index--;
return tmp;
}
const Iterator operator-(int left)
{
return Iterator(pvec, index - left);
}
};
//重载迭代器的解引用
template<typename T>
T& Iterator<T>::operator*()const
{
return (*pvec)[index]; //vec[0];
}