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汇总的更多相关文章
- STL iterator和reverse_iterator
先看一段代码: #include <iostream> #include <deque> #include <algorithm> #include <ite ...
- 学习笔记-C++ STL iterator与对指针的理解-20170618
vector的itrerator支持random access #include<iostream> #include<vector> using namespace std; ...
- c++ stl 使用汇总(string,vector,map,set)
1.string 1>substr(),截取字串的方法.返回一个从指定位置开始,并具有指定长度的子字符串.参数 start(必选),所需的子字符串的起始位置.字符串中第一个字符的索引为 0.le ...
- STL坑汇总
1. Q:vector的push_back()方法到底做了些什么? 为什么声明写的是void push_back (const value_type& val); A:的确,乍一看,似乎pus ...
- STL源码分析-iterator(迭代器)
1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...
- C++ Standard Template Library STL(undone)
目录 . C++标准模版库(Standard Template Library STL) . C++ STL容器 . C++ STL 顺序性容器 . C++ STL 关联式容器 . C++ STL 容 ...
- STL 简介,标准模板库
这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL. 当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...
- C++ STL中迭代器失效的问题
my_container.erase(iter); 其中my_container是STL的某种容器,iter是指向这个容器中某个元素的迭代器.如果不是在for,while循环中,这种方式删除元素没有问 ...
- STL,ATL,WTL之间的联系和区别
STL即 Standard Template Library (标准模板库) STL是惠普实验室开发的一系列软件的统称.它是由Alexander Stepanov.Meng Lee和David R M ...
随机推荐
- chrome浏览器跨域模式设置
做前后分离的webapp开发的时候,出于一些原因往往需要将浏览器设置成支持跨域的模式,好在chrome浏览器就是支持可跨域的设置,网上也有很多chrome跨域设置教程.但是新版本的chrome浏览器提 ...
- 生成全局唯一ID
在实际业务处理中,有时需要生成全局唯一ID来区别同类型的不同事物,介绍一下几种方式及其C++实现 //获取全局唯一ID //server_id为服务的id,因当同一个服务部署在多个服务器上时,需要区别 ...
- DevExpress ASP.NET Dev控件客户端事件 ClientSideEvents
原文地址:http://www.cnblogs.com/allenlf/p/4171189.html
- Angular2入门-架构总览
▓▓▓▓▓▓ 大致介绍 在3月23日,Angular4正式发布(没有3).似乎现在学Angular2又晚了,又晚一步-_-||.Angular2在Angular1的基础上有了较大的改变.之前向一个同学 ...
- 常用linux基础命令(持续更新...)
删除 空目录 rmdir非空目录 rm -rf 目录名字-r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 删除文件命令rm -f 文件名将会强行删除文件,且无提 ...
- spring boot +Thymeleaf+mybatis 集成通用PageHelper,做分页
controller: /** * 分页查询用户 * @param request * @param response * @return * @throws Exception */ @ ...
- Apache 在 htaccess 禁止访问 和 conf 中的 禁止访问 区别
相信熟悉Web Server的人一定熟悉Apahce.相信熟悉Apahce的人一定知道URL Rewrite.Apache的mod_rewrite模块,可以帮助人们构造出各种各样美化后的URL.在Ap ...
- IIS Express被局域网访问
在 文件夹 C:\Users\administrator\Documents\IISExpress\config 下面 applicationhost.config 文件里 找到相应的项目 如 < ...
- http文件上传/下载
package unit; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputSt ...
- js最后深入总结
js常用事件: click #点击事件 hover #鼠标漂浮事件,,鼠标移到上面就触发事件 blur #失去焦点就触发事件,多用于文本框操作 focus #获得焦点就触发事件, change ...