STL——iterator

一、概述
Iterator(迭代器)模式又称Cursor(游标)模式,

根据STL中的分类,iterator包括:
Input Iterator:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。(istream)

--------------------------------------

*iter         读取实际元素

iter        向前步进(传回新位置)

iter         向前步进 (传回旧位置)

== !=         判断两个迭代器是否相等

TYPE(iter)    复制迭代器

--------------------------------------
Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。(ostream, inserter)

--------------------------------------
*iter = value       将数值写到迭代器所指位置

--------------------------------------
Forward Iterator:是Input Iterator和Output Iterator的结合,具有Input的全部功能和Output的大部分功能。
--------------------------------------

iter1 = iter2       赋值
--------------------------------------

Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。(list, set, multiset, map, multimap)

--------------------------------------

--iter

iter--

--------------------------------------
Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。(vector, deque,string,array)
--------------------------------------

iter[n]

iter =n; iter-=n; iter n; n ter;

iter1-iter2; iter1<iter2...

--------------------------------------

二、结构
Iterator模式的结构如下图所示:
 
              图、stl的图未找到,此处为java中的迭代器模式图

四、优缺点
正如前面所说,与集合密切相关,限制了 Iterator模式的广泛使用,就个人而言,我不大认同将Iterator作为模式提出的观点,但它又确实符合模式“经常出现的特定问题的解决方案”的特质,以至于我又不得不承认它是个模式。在一般的底层集合支持类中,我们往往不愿“避轻就重”将集合设计成集合 Iterator 的形式,而是将遍历的功能直接交由集合完成,以免犯了“过度设计”的诟病,但是,如果我们的集合类确实需要支持多种遍历方式(仅此一点仍不一定需要考虑 Iterator模式,直接交由集合完成往往更方便),或者,为了与系统提供或使用的其它机制,如STL算法,保持一致时,Iterator模式才值得考虑。

五、举例
可以考虑使用两种方式来实现Iterator模式:内嵌类或者友元类。通常迭代类需访问集合类中的内部数据结构,为此,可在集合类中设置迭代类为):
(注:、虽然下面这个示例是本系列所有示例中花费我时间最多的一个,但我不得不承认,它非常不完善,感兴趣的朋友,可以考虑参考下面的参考材料将其补充完善,或提出宝贵改进意见。、我本想考虑将其封装成与STL风格一致的形式,使得我们遍历二叉树必须通过Iterator来进行,但由于二叉树在结构上较线性存储结构复杂,使访问必须通过Iterator来进行,但这不可避免使得BinaryTree的访问变得异常麻烦,在具体应用中还需要认真考虑。、以下只提供了Inorder<中序>遍历iterator的实现。)
#include <assert.h>

#include <iostream>
#include <xutility>
#include <iterator>
#include <algorithm>
using namespace std;

template <typename T>
class BinaryTree;
template <typename T>
class Iterator;

template <typename T>
class BinaryTreeNode
{

public:
     typedef BinaryTreeNode<T> NODE;
     typedef BinaryTreeNode<T>* NODE_PTR;

BinaryTreeNode(const T& element) : data(element), leftChild(NULL), rightChild(NULL),parent(NULL) { }
     BinaryTreeNode(const T& element, NODE_PTR leftChild, NODE_PTR rightChild)
         :
data(element), leftChild(leftChild), rightChild(rightChild), parent(NULL)
     {

         if (leftChild)
             leftChild->setParent(this);
         if (rightChild)
             rightChild->setParent(this);
     }

    
     T getData(void) const { return data; }
     NODE_PTR getLeft(void) const { return leftChild; }
     NODE_PTR getRight(void) const { return rightChild; }
     NODE_PTR getParent(void) const { return parent; }
     void SetData(const T& data) { this->data = item; }
     void setLeft(NODE_PTR ptr) { leftChild = ptr; ptr->setParent(this); }
     void setRight(NODE_PTR ptr) { rightChild = ptr; ptr->setParent(this); }
     void setParent(NODE_PTR ptr) { parent = ptr; }
private:
     T data;
     NODE_PTR leftChild;
     NODE_PTR rightChild;
     NODE_PTR parent;   // pointer to parent node, needed by iterator

     friend class BinaryTree<T>;
};

stl::iterator初探

c++中用于数据管理的话,在不考虑高效率的前提下,容器是个不错的选择(要求高效率的话请用数组).用到了STL一般也要和iterator打交道,一开始时以为它也就是个指向容器元素的指针,实际上它是个对象,以下为测试实例:

typedef struct stNode{

  int Id;

  char data[10];

}Node;
typedef std::vector<Node> vnode;  // Node链表

typedef std::vector<Node*> vpnode;  // Node指针链表

vnode node;

vpnode pnode;

bool init_vector()    // 初始化两个链表

{

  for (int i = 0; i < 10; i++)    // 初始化node链表

  {

    Node tmp_node;

    memset(&tmp_node, 0, sizeof(Node));

    tmp_node.Id = i+1;

    sprintf_s(tmp_node.data,10,"Name%d",i+1);

    node.push_back(tmp_node);

  }

  for (int j = 0; j < 10; j++)    // 初始化pnode链表

  {

    Node *tmp_node1 = new Node;

    tmp_node1->Id = j+11;

    sprintf_s(tmp_node1->data,10,"pName%d",j+11);

    pnode.push_back(tmp_node1);

  }

  return true;

}

Node* getNode(const int Id)    // 根据Id返回对应的Node指针

{

  if (Id < 0)return(NULL);

  for (vnode::iterator it = node.begin(); it != node.end(); it++)  // it是指向元素的指针(暂时称为指针)

  {

    if (Id == (*it).Id)    // 看这用法,不就是指针的用法吗?

    {

      //return it;  错误

      return &(*it);   // 正确, 此处可以看出,it并不是真正的指针,它只是具有指针某些特性的一个对象

    }

  }

  for (vpnode::iterator itp = pnode.begin(); itp != pnode.end(); itp++)  // 此时itp是二级指针

  {

    if (Id == (*itp)->Id)

    {

      return (*itp);

    }

  }

  return(NULL);

}

Node getNode2(const int Id)  // 根据Id返回对应的Node实体

{

  Node rtNode;

  memset(&rtNode, 0x00, sizeof(Node));

  if (Id < 0)

    return(rtNode);

  for (vnode::iterator it = node.begin(); it != node.end(); it++)  // it是指向元素的指针

  {

    if (Id == (*it).Id)

    {

      rtNode = (*it);  // 返回Node实体

      goto exit;

    }

  }

  for (vpnode::iterator itp = pnode.begin(); itp != pnode.end(); itp++)  // 此时itp是二级指针

  {

    if (Id == (*itp)->Id)

    {

      rtNode = (*(*itp));    // 不算是指针的用法?

      goto exit;

    }

  }

exit:

  return(rtNode);

}

// 测试代码

int _tmain(int argc, _TCHAR* argv[])

{

  int id[] = {5,7,9,11,19,21,23};

  init_vector();
  Node *vectorNode = new Node;

  for (int i = 0; i < sizeof(id)/sizeof(int); i++)

  {

    vectorNode = getNode(id[i]);

    if(vectorNode != NULL)

      printf("Found %d\n",vectorNode->Id);

    else

      printf("Not Found %d\n",id[i]);

  }

  
  Node vecNode;

  for (int i = 0; i < sizeof(id)/sizeof(int); i++)

  {

    vecNode = getNode2(id[i]);

    if(vecNode.Id != 0)

      printf("Found %d\n",vecNode.Id);

    else

      printf("Not Found %d\n",id[i]);

  }

  return 0;

}

stl::iterator汇总的更多相关文章

  1. STL iterator和reverse_iterator

    先看一段代码: #include <iostream> #include <deque> #include <algorithm> #include <ite ...

  2. 学习笔记-C++ STL iterator与对指针的理解-20170618

    vector的itrerator支持random access #include<iostream> #include<vector> using namespace std; ...

  3. c++ stl 使用汇总(string,vector,map,set)

    1.string 1>substr(),截取字串的方法.返回一个从指定位置开始,并具有指定长度的子字符串.参数 start(必选),所需的子字符串的起始位置.字符串中第一个字符的索引为 0.le ...

  4. STL坑汇总

    1. Q:vector的push_back()方法到底做了些什么? 为什么声明写的是void push_back (const value_type& val); A:的确,乍一看,似乎pus ...

  5. STL源码分析-iterator(迭代器)

    1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...

  6. C++ Standard Template Library STL(undone)

    目录 . C++标准模版库(Standard Template Library STL) . C++ STL容器 . C++ STL 顺序性容器 . C++ STL 关联式容器 . C++ STL 容 ...

  7. STL 简介,标准模板库

    这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL.  当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...

  8. C++ STL中迭代器失效的问题

    my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...

  9. STL,ATL,WTL之间的联系和区别

    STL即 Standard Template Library (标准模板库) STL是惠普实验室开发的一系列软件的统称.它是由Alexander Stepanov.Meng Lee和David R M ...

随机推荐

  1. nginx架构与基础概念

    1       Nginx架构 Nginx 高性能,与其架构有关. Nginx架构: nginx运行时,在unix系统中以daemon形式在后台运行,后台进程包含一个master进程和多个worker ...

  2. maven+selenium+java+testng+jenkins自动化测试

    最近在公司搭建了一套基于maven+selenium+java+testng+jenkins的自动化测试框架,免得以后重写记录下 工程目录 pom.xml <project xmlns=&quo ...

  3. phaser小游戏框架学习(一)

    这两天由于项目的需要,所以简单学了一下phaser框架. 官网:http://phaser.io/ 还有一个phaser小站,是中文的网站,但是内容不如英文文档全,大家也可以去看这个网站,需要查阅AP ...

  4. ios swift UITextView高度自适应

    在ios开发中,用到多行输入时一般都会用到UITextView.常见的比如说聊天输入框,评论输入框等,当用户输入多内容时,我们希望高度能根据用户输入的内容扩大而扩大.其实实现这个功能也不是很难,只需要 ...

  5. P3321 [SDOI2015]序列统计 FFT+快速幂+原根

    \(\color{#0066ff}{ 题目描述 }\) 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这 ...

  6. 微信网页授权操作逻辑封装-C#实例

    http://blog.csdn.net/u011127019/article/details/52650619

  7. 「模拟赛20180406」膜树 prufer编码+概率

    题目描述 给定一个完全图,保证\(w_{u,v}=w_{v,u}\)且\(w_{u,u}=0\),等概率选取一个随机生成树,对于每一对\((u,v)\),求\(dis(u,v)\)的期望值对\(998 ...

  8. 洛谷 P1028 数的计算

    嗯... 首先这道题想到的就是递推.... 但是递推失败 (不知道自己是怎么想的 然后又想打一个暴力,但是数的最高位太难存储了,所以又放弃了(并且好像这个暴力大约500就会炸... 然后看了题解,才发 ...

  9. c++中STL中的next_permutation函数基本用法

    对于next_permutation函数是针对于排列组合问题的库函数,它的排序方式是按照字典的方式排列的·: 如以下代码对于next_permutation函数的初步解释: #include<c ...

  10. django文件配置

    先是 staticfile 文件配制 STATTCFILE=(os.path.join(BASE_DIR,'static'),) 然后是数据库配置  : DATABASES = { 'default' ...