3.STL简单的迭代器实现(含源码)

我使用vs2015写的程序(源码下载

STL的中心思想在于将容器(container)和算法(algorithms)分开,彼此独立设计,最后再以一贴胶着剂将它们撮合在一起,而这个胶着剂就是迭代器(iterator)。

迭代器是访问容器的工具。注意,先有容器,才有访问容器的工具。迭代器需要了解容器的特性才能实现,这决定了迭代器必须要深入到容器内部,于是STL干脆把迭代器的开发交给容器的设计者。

迭代器的开发分为三步:

1.      元素的设计;

2.      装载元素的容器的设计;

3.      访问容器的迭代器的设计;

为了方便起见,我设计的是一款基于单向链表的迭代器。根据迭代器的开发步骤,首先给出链表节点的设计代码。

ListItem.h:

<pre name="code" class="cpp">#ifndef _CGH_LIST_ITEM_
#define _CGH_LIST_ITEM_

// 定义链表节点类型
template<typename T>
class ListItem{
public:
         Tvalue() const{ return _value; }
         ListItem*next() const{ return _next; }
         ListItem(Tvalue) : _value(value), _next(NULL) { }
public:
         T_value;
         ListItem*_next;
};

#endif

链表节点主要包含两个成员变量:

1.      保存节点值的_value;

2.      指向下一个节点的_next指针。

接下来是容器的设计,我开发的容器是单向链表,单向链表类的代码如下:

template<typename T>
class cghList{
public:
         voidinsert_front(T value);  // 插入节点到链表头部
         voidinsert_end(T value);  // 插入节点到链表尾部
         voiddisplay(std::ostream& os = std::cout)const; // 从头到尾打印链表
         cghList():_end(NULL), _front(NULL) { } // 构造函数,初始化头指针、尾指针
         ListItem<T>*front()const{ return _front; } // 返回头指针
         ListItem<T>*end()const{ return _end; } // 返回尾指针
private:
         ListItem<T>*_end;  // 链表尾指针
         ListItem<T>*_front;  // 链表头指针
         long_size;  // 链表长度
};

单向链表的成员变量和成员函数的作用很简单,全是基本的链表操作。成员函数的实现不复杂,主要是对链表的头插和尾插。成员函数的实现代码如下。

// 插入节点到链表头部
template<typename T>
void cghList<T>::insert_front(T value){
         cghList<T>::_size++;
         ListItem<T>*tmp = new ListItem<T>(value);
         if(typename cghList<T>::_front == NULL) {
                   typenamecghList<T>::_front = tmp;
                   typenamecghList<T>::_end = tmp;
         }
         else{
                   tmp->_next= _front;
                   _front= tmp;
         }
}

// 插入节点到链表尾部
template<typename T>
void cghList<T>::insert_end(T value){
         cghList<T>::_size++;
         ListItem<T>*tmp = new ListItem<T>(value);
         if(typename cghList<T>::_front == NULL) {
                   typenamecghList<T>::_front = tmp;
                   typenamecghList<T>::_end = tmp;
         }
         else{
                   typenamecghList<T>::_end->_next = tmp;
                   typenamecghList<T>::_end = typename cghList<T>::_end->_next;
         }
}

         //从头到尾打印链表
template<typename T>
void cghList<T>::display(std::ostream&os = std::cout)const{
         if(typename cghList<T>::_front == NULL || typename cghList<T>::_end ==NULL){
                   return;
         }
         ListItem<T>*tmp = typename cghList<T>::_front;
         while(tmp != NULL){
                   std::cout<< tmp->_value << std::endl;
                   tmp= tmp->_next;
         }
}

有了容器和容器的元素,接下来就是最关键的迭代器啦~

上代码:

cghIterator.h

#ifndef _CGH_ITERATOR_
#define _CGH_ITERATOR

template<typename Item>
struct ListIter : public std::iterator<std::forward_iterator_tag,Item>
{
         Item*ptr; // 容器与迭代器的纽带

         ListIter(Item*p = 0) :ptr(p) { } // 构造函数,初始化ptr指针
         Item&operator*() const { return *ptr; } // 返回容器(本例为链表)的节点引用
         Item*operator->() const { return ptr; } // 返回容器(本例为链表)的节点地址

         //  指向容器(本例为链表)的下一个节点,i++
         ListIter&operator++(){
                   ptr= ptr->next();
                   return*this;
         }

         //  指向容器(本例为链表)的下一个节点,++i
         ListIter&operator++(int){
                   ListItertmp = *this;
                   ++*this;
                   returntmp;
         }

         //判断两节点是否相等,也就是判断两节点的地址是否相同
         booloperator==(const ListIter& i) const{
                   returnptr == i.ptr;
         }

         //判断两节点是否不相等,也就是判断两节点的地址是否不相同
         booloperator!=(const ListIter& i) const{
                   returnptr != i.ptr;
         }
};

#endif

迭代器直接用struct定义的,而不是class,为什么呢?因为class的成员变量和成员函数默认是private访问权限,而struct的成员变量和成员函数默认是public访问权限。设计成struct也就是说任何人都可以使用迭代器的所有属性和功能。

本迭代器唯一也是最重要的成员成员变量是ptr指针,ptr其实就是ListItem*类型,是联系链表和迭代器的桥梁。

接下来是测试容器的代码:

// iterator.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cghList.h"
#include "cghIterator.h"
#include "ListItem.h"
#include<iostream>

int _tmain(int argc, _TCHAR* argv[])
{
         cghList<int>myList; //  定义容器

         //往容器中加入节点
         for(int i = 0; i < 5; i++){
                   myList.insert_front(i);
         }

         //从前向后打印节点
         //myList.display();

         for(ListIter<ListItem<int>> iter = myList.front(); iter != myList.end();iter++){
                   std::cout<< iter->_value << std::endl;
         }
         system("pause");
         return0;
}

有了这个雏形,就可以往里面添砖加瓦了,有兴趣的童鞋可以在此基础上修改,写出自己的功能强大的迭代器!

时间: 2024-10-09 21:42:27

3.STL简单的迭代器实现(含源码)的相关文章

17+个ASP.NET MVC扩展点,含源码{转}

1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig.在自定义的HttpModule中,可以将一个方法注册到HttpApplication的任意一个事件中,在之后执行HttpApplication一些列事件时,按照事件的顺序(事件又按照添加方法先后的顺序)执行注册在事件中的方法! namespace MvcStore.Models { public class Excute

c++实现游戏开发中常用的对象池(含源码)

c++实现游戏开发中常用的对象池(含源码) little_stupid_child2017-01-06上传 对象池的五要素: 1.对象集合 2.未使用对象索引集合 3.已使用对象索引集合 4.当前使用量 5.最大使用量 http://download.csdn.net/download/little_stupid_child/9730912

微信公众平台开发-access_token获取及应用(含源码)

微信公众平台开发-access_token获取及应用(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 很多系统中都有access_token参数,对于微信公众平台的access_token参数,微信服务器判断该公众平台所拥有的权限,允许或者禁止公众平台进行当前的操作. 一.access_token作用及使用场景 (一)access_token的作用 access_token由公众号的AppID和AppSecret组成,所以具有识别公众号的作用. (二)access_token的使用场景

MultiThread(VS2013 MFC多线程-含源码-含个人逐步实现文档)

原文:http://download.csdn.net/download/jobfind/9559162 MultiThread(VS2013 MFC多线程-含源码-含个人逐步实现文档).rar

Javaweb实现的优优图书商城(含源码)

原文地址:http://www.cnblogs.com/liaoyu/p/uushop.html 源码地址:https://github.com/liaoyu/uushop 贴出一个大学时做的小项目,供有需要的朋友参考,名为优优图书商城,下面为关于它的一些介绍 主要功能介绍: 用户注册.登录.个人信息管理.通过邮件找回密码 图书搜索.购买.在线浏览,购物车管理 后台echart图表显示.源代码在线编辑 主要技术: 数据库 : mysql 后台语言: Java 后台框架: Hibernate Sp

手把手教你从最基本的Java工程搭建SpringMVC+SpringDataJPA+Hibernate(含源码下载)

转载请注明出处:http://blog.csdn.net/anxpp/article/details/51415366,谢谢! 本文会介绍从一个最基本的java工程,到Web工程,到集成Spring.SpringMVC.SpringDataJPA+Hibernate. 平时我们可能是通过一个模板搭建一个工程,或者是直接导入一个项目,而本文选择从最基本的java工程开始,目的是为了展示更多原理. 当然,我们还是从一个最基本的Maven工程开始,其实普通的非Maven工程,搭建过程几乎是一模一样的,

简单Eclipse关联support.v4源码

最近很多人问我怎么关于v4包的API,其实这些都可以通过关联源码解决.但是很多人会发现当我们按住ctrl鼠标点击相应的方法或类时却发现无法查看,且无关联源码的按钮项.无法进行任何操作. 如下图所示: 那么我们需要怎么操作才能正确关联v4.v7.support等的其他源码呢?下面我简单做下操作示范.分别在windows和Mac下进行操作.操作步骤基本相类似,只是界面略微不同.这里只对win8.1下做详解.读者可根据操作步骤自己关联一下. 1.Windows平台下(win8.1): 1.1.在Ecl

C++ TinyXml操作(含源码下载)

前言 TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译,使用TinyXML进行C++ XML解析,使用简单,容易上手.这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树. DOM模型即文档对象模型,是将整个文档分成多个元素(如书.章.节.段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系. TinyXML介绍 在TinyXML中,根据XML的各种元素来定义了一些类:TiXmlBase

[转] - 使用Qt作窗口截屏(含源码)

截屏(screenshot),就是将屏幕上的东西拷贝下来存成图片文件.介绍的好像有点多余:(,那我们就直接切入正题. QPixmap提供了两个函数grabWidget和grabWindow可以将屏幕上的窗体存成一个QPixmap格式的图片,很容易再将QPixmap存成文件.函数使用很简单,两行代码就可以.QPixmap pixmap = QPixmap::grabWidget(this);//this是调用该函数的QWidget *指针pixmap.save(“widget.png”,”png”