在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识。这里我通过几个小的DEMO,来看看迭代器。首先我实现了一个十分简陋的vector类:
- template <class T>
- class vector {
- private:
- T* pbegin;
- int n; //当前大小
- public:
- vector() {
- pbegin = new T[100]; //暂时先固定大小
- n = 0;
- }
- T* begin() {
- return pbegin;
- }
- void insert(T d){
- pbegin[n++] = d;
- }
- typedef T* iterator; //vector的迭代器就是基础指针类型
- };
- //测试vector
- vector<int> a;
- a.insert(1);
- a.insert(2);
- vector<int>::iterator itra;
- itra = a.begin();
- printf("%d/n", *itra);
- itra++;
- printf("%d/n", *itra);
- itra--; //基础指针类型都支持++,--,+,-等操作符
- printf("%d/n", *itra);
哇~~,原来vector的迭代器那么简单,那么,我们来考虑一下List,这是链表,我们知道,链表每个元素都存储在不同的位置,我们一般通过指向下一个元素的next指针来找到下一个元素。那么,我们怎么样来设计一个迭代器,然后可以直接对这个迭代器进行++,--等操作二遍历访问整个链表呢:
- template <class T>
- class List{
- private:
- struct Node{ //链表的节点
- T data;
- Node* next;
- };
- Node* pbegin; //表头
- class List_iterator{ //链表的迭代器
- Node* cur; //当前指向
- public:
- void operator = (Node* ptr) {
- cur = ptr;
- }
- void operator ++ () {
- cur = cur->next;
- }
- // ...还可以重载-- + -等操作符
- T operator * (){
- return cur->data;
- }
- };
- public :
- List() {
- pbegin=NULL;
- }
- Node* begin() {
- return pbegin;
- }
- void insert(T d) {
- Node* p=pbegin;
- while(p && p->next) p=p->next;
- Node* t = new Node;
- t->data = d;
- t->next = NULL;
- if(pbegin==NULL)
- pbegin = t;
- else
- p->next = t;
- }
- typedef List_iterator iterator; //List的迭代器是一个类
- };
- /测试List
- List<int> b;
- b.insert(1);
- b.insert(2);
- List<int>::iterator itrb;
- itrb = b.begin();
- printf("%d/n", *itrb);
- itrb++; // 该迭代器只支持++
- printf("%d/n", *itrb);
通过这两个例子,可以看出,迭代器是跟容器紧密结合的,不同的容器,它的迭代器不同,但是,他们有共同的目标,就是可以通过该迭代器,来遍历访问这个容器里面的元素。这样带来的好处是在STL设计算法时,可以脱离容器而设计更加通用的算法。比如,在容器中查找一个元素。查找,这个操作一般来说就是遍历整个集合,然后找到那个要找的元素,但是,如果没有迭代器,我们需要为vector和List设计两个查找算法,因为找下一个元素在vector和List中的操作不同。同样的思想却要两套代码,显然这是不优秀的。
有了模板,我们可以将算法和特定的数据分离开来,而有了迭代器,我们可以将算法和特定的容器分离开来。
上面list的例子中,结构体,迭代器都在List类内部声明,我觉得这样不好,不利于程序扩展,做了以下修改并通过验证
template <class T>
struct Node//链表的节点
{
T data;
struct Node<T> *next;
};
template <class T>
class List_iterator //链表的迭代器
{
Node<T>* cur; //当前指向
public:
void operator = (Node<T>* ptr)
{
cur = ptr;
}
void operator ++ ()
{
cur = cur->next;
}
T operator * () // ...还可以重载-- + -等操作符
{
return cur->data;
}
};
template <class T>
class List
{
private:
Node<T> *pbegin; //表头
public :
List()
{
pbegin=NULL;
}
Node<T>* begin()
{
return pbegin;
}
void insert(T d)
{
Node<T>* p=pbegin;
while(p && p->next) p=p->next;
Node<T>* t = new Node<T>;
t->data = d;
t->next = NULL;
if(pbegin==NULL)
pbegin = t;
else
p->next = t;
}
typedef List_iterator<T> iterator; //List的迭代器是一个类
};
int _tmain(int argc, _TCHAR* argv[])
{
List<int> b;
b.insert(1);
b.insert(2);
List<int>::iterator itrb;
itrb = b.begin();
printf("%d/n", *itrb);
itrb++; // 该迭代器只支持++
printf("%d/n", *itrb);
system("pause");
return 0;
}