迭代器的设计要点 《STL源码剖析》读书笔记

来源:互联网 发布:linux 双系统 虚拟机 编辑:程序博客网 时间:2024/06/15 20:25

Slowing down your step,you will enjoy more ---wonderful

 最初 对于迭代器的印象 是 迭代器能够访问容器中的元素,并对容器中的元素进行操作。实际上这也是作为容器使用者角度所看到的。

在阅读源码的过程中,越来越感觉到,迭代器的设计和容器应该说是没有直接的联系。真正和迭代器设计相关的是容器的节点,而不是容器的本身。

《STL源码剖析》中也提到 容器的本身和节点是不同的结构(如List本身和List节点结构不同)。  我们设计迭代器的时候更加应该关注容器节点,而不是容器。

  下面以一个List 容器为例,

   List 节点(node)结构:

template<class T>struct __list_node{   typedef void* void_pointer;// void_pointer 现在表示空类型指针   void_pointer prev;// 型别为void* ,也可以定义为__list_node<T*>*类型   void_pointer next;  T data;}


List容器的迭代器:

 

    迭代器要求能够访问容器中的所有节点,并有能力进行一些其他的操作。因此设计迭代器就要研究节点的结构:

  如果迭代器要访问节点的值  ,需要节点中的data,如下:

                                            reference operator*() const { return (*node).data; }  

  如果迭代器要访问节点下一个节点  只需要获得节点中的next指针,如下:

 self operator ++(){           node = (link_type)(*node).next;//定义时候为void* 所以这里要强制类型转换          return *this;}
  如果迭代器要访问节点前一个节点  只需要获得节点中的prev指针,如下:
 self operator --(){           node = (link_type)(*node).prev;//定义时候为void* 所以这里要强制类型转换          return *this;}
  上面代码的实现,都只需要研究节点的结构就可以做到。而无需关心容器是怎么实现。

 实际上容器真正和迭代器关联起来,是通过把容器中的一个节点交给迭代器,然后迭代器就可以根据这个节点进行++,-- ,==,取值等操作,访问容器的其他节点。

如下:

 

// list.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<iostream>#include<list>#include<algorithm>using namespace std;int _tmain(int argc, _TCHAR* argv[]){int i;list<int> ilist;cout<<"size="<< ilist.size()<<endl;ilist.push_back(0);ilist.push_back(1);    ilist.push_back(2);ilist.push_back(3);cout<<"size="<< ilist.size()<<endl;    // 给迭代器初始化类型,让Template<class T> 中的 T 为 intlist<int>::iterator ite;//下面注意了,这里给迭代器实例化,让迭代器指向容器中的一个节点。//begin(),end() 函数就是用来取得容器中的一个节点的函数//调用了迭代器中的 != ,++ ,*() 用来操作容器中节点for(ite = ilist.begin();ite != ilist.end();++ite)cout<< *ite<<' ';cout<<endl;return 0;}

     使用迭代器的时候: 先让迭代器知道容器持有对象的类型                                           

list<int>::iterator ite; //持有int 

    然后让迭代器指向容器中的一个节点:和容器联系真正的开始

           ite = ilist.begin();//迭代器获得容器中的一个节点

    最后调用迭代器中已经定义好的一些操作,就可以操作容器了。

原创粉丝点击