C++ 迭代器模式实现
STL模板库中有大量迭代器实现,这些迭代器隔离了算法实现与访问接口,我们也可以编写属于自己的迭代器。STL中的迭代器均继承至一个通用迭代器接口:
template <class _Category, class _Tp, class _Distance = ptrdiff_t,
class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
typedef _Category iterator_category; //迭代器类型
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Pointer pointer;
typedef _Reference reference;
};
迭代器类型用于指明实例化迭代器的标签,如:输入迭代器(写)、输出迭代器(读)、随机访问迭代器等,算法可通过不同迭代器种类来实现各版本。
__distance算法就针对不同迭代器不同的实现:
template <class _InputIterator, class _Distance>
inline void __distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, input_iterator_tag)
{
while (__first != __last) { ++__first; ++__n; }
} template <class _RandomAccessIterator, class _Distance>
inline void __distance(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Distance& __n, random_access_iterator_tag)
{
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
__n += __last - __first;
}
所有的迭代器种类声明如下:
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
迭代器的重要方法如下:
T& operator*() const
T* operator->() const
bool operator==(const iterator & __x) const
bool operator!=(const iterator & __x) const
iterator& operator++()
iterator operator++(int)
这样就可以实现自己的迭代器了:
#include <iostream>
#include <iterator> using namespace std; template <typename T>
struct _A_node {
_A_node *next;
_A_node *prev;
T data;
}; template <typename T>
class A_Iterator:public iterator<forward_iterator_tag,T>
{
private:
typedef A_Iterator<T> self; _A_node<T> *_node;
void incr()
{
_node = _node->next;
} void decr()
{
_node = (_A_node<T>*)_node->prev;
} public:
A_Iterator():_node(0) {}
A_Iterator(_A_node<T> *x):_node(x) {}
~A_Iterator() {} T& operator*() const { return _node->data;}
T* operator->() const {return &(operator*());} bool operator==(const self& __x) const {
return _node == __x._node;
} bool operator!=(const self& __x) const {
return _node != __x._node;
} self& operator++() { incr(); return *this;}
self operator++(int) { self __tmp = *this; incr(); return __tmp;} self& operator--() {decr();return *this;}
self operator--(int) {self __tmp = *this; decr();return __tmp;} }; template <typename T>
class A {
private:
typedef T Node;
_A_node<T> *pNode;
public:
typedef A_Iterator<T> iterator;
typedef _A_node<T> _Node; A() {
pNode = new _A_node<T>;
pNode->next = pNode;
pNode->prev = pNode;
}
~A() {
//add delete node function here
delete pNode;
} iterator begin() {return (_Node *)(pNode->next);}
iterator end() {return pNode;} ///////////////// method /////////////////////
void push(T value)
{
_A_node<T> *v = new _A_node<T>;
v->data = value; v->next = pNode->next;
pNode->next->prev = v; pNode->next = v;
v->prev = pNode; } T pop()
{
T value; _Node *next = pNode->next;
pNode->next = next->next;
next->prev = pNode; next->prev = next;
next->next = next; value = next->data;
delete next; return value;
}
}; int main(int argc, char *argv[])
{
A<int> a;
a.push(1);
a.push(2);
a.pop();
for(A<int>::iterator iter = a.begin();iter != a.end();iter++) {
*iter = 3;
std::cout << "value:" << *iter << std::endl;
} int b = a.pop(); std::cout << (a.begin() == a.end()) << ",b:" << b << std::endl;
return 0;
}
若需增加const_iterator则需要进行重写另一个iterator,也可以通过修改iterator模板声明格式进行修改,满足其iterator格式,最终版本如下:
#include <iostream>
#include <iterator> using namespace std; template <typename T>
struct _A_node {
_A_node *next;
_A_node *prev;
T data;
}; template <class T,class Ref,class Ptr>
class A_Iterator:public iterator<forward_iterator_tag,T>
{
public:
typedef A_Iterator<T,T&,T*> iterator;
typedef A_Iterator<T,const T&,const T*> const_iterator;
private:
typedef A_Iterator<T,Ref,Ptr> self; _A_node<T> *_node;
void incr()
{
_node = _node->next;
} void decr()
{
_node = (_A_node<T>*)_node->prev;
} public:
A_Iterator():_node(0) {}
A_Iterator(_A_node<T> *x):_node(x) {}
~A_Iterator() {} Ref operator*() const { return _node->data;}
Ptr operator->() const {return &(operator*());} bool operator==(const self& __x) const {
return _node == __x._node;
} bool operator!=(const self& __x) const {
return _node != __x._node;
} self& operator++() { incr(); return *this;}
self operator++(int) { self __tmp = *this; incr(); return __tmp;}
}; template <typename T>
class A {
private:
typedef T Node;
_A_node<T> *pNode;
public:
typedef typename A_Iterator<T,T&,T*>::iterator iterator;
typedef typename A_Iterator<T,const T&,const T*>::const_iterator const_iterator;
typedef _A_node<T> _Node; A() {
pNode = new _A_node<T>;
pNode->next = pNode;
pNode->prev = pNode;
}
~A() {
//add delete node function here
delete pNode;
} iterator begin() {return (_Node *)(pNode->next);}
iterator end() {return pNode;} const_iterator const_begin() const {return (_Node *)(pNode->next);}
const_iterator const_end() const {return pNode;} ///////////////// method /////////////////////
void push(T value)
{
_A_node<T> *v = new _A_node<T>;
v->data = value; v->next = pNode->next;
pNode->next->prev = v; pNode->next = v;
v->prev = pNode; } T pop()
{
T value; _Node *next = pNode->next;
pNode->next = next->next;
next->prev = pNode; next->prev = next;
next->next = next; value = next->data;
delete next; return value;
}
}; int main(int argc, char *argv[])
{
A<int> a;
a.push(1);
a.push(2);
//a.pop();
/*
for(A<int>::iterator iter = a.begin();iter != a.end();iter++) {
*iter = 3;
std::cout << "value:" << *iter << std::endl;
}
*/
//A<int>::const_iterator iter = a.const_begin(); for(A<int>::const_iterator iter = a.const_begin();iter != a.const_end();iter++) {
//*iter = 3;
std::cout << "value:" << *iter << std::endl;
} int b = a.pop(); std::cout << (a.begin() == a.end()) << ",b:" << b << std::endl;
return 0;
}
C++ 迭代器模式实现的更多相关文章
- C#设计模式-迭代器模式
一. 迭代器(Iterator)模式 迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的 ...
- 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)
上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...
- 迭代器模式/iterator模式/对象行为型模式
意图 又名:游标(Cursor): 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 动机 一个聚合对象,提供访问元素的方法,而有不暴露它的内部结构.如list,将对列表的访问 ...
- C#设计模式系列:迭代器模式(Iterator)
迭代器模式把对象的职责分离,职责分离可以最大限度减少彼此之间的耦合程度,从而建立一个松耦合的对象.职责分离的要点是对被分离的职责进行封装,并以抽象的方式建立彼此之间的关系. 1.迭代器模式简介 1.1 ...
- php实现设计模式之 迭代器模式
<?php /*迭代器模式: 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.(行为模式) * 1.迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的 ...
- Java源代码-迭代器模式
Java无疑是最成功的项目之一了,而在其中学习设计模式和架构设计,无疑是最好不过了. 概念: 提供一种方法访问容器中的各个元素,而又不暴露该对象的内部细节. 使用场景: 和容器经常在一起,我们定义了一 ...
- PHP设计模式 迭代器模式
迭代器模式,在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素.相比于传统的编程模式,迭代器模式可以隐藏遍历元素所需要的操作. AllHacl.php <?php namespace Ba ...
- [Head First设计模式]生活中学设计模式——迭代器模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- js设计模式总结-迭代器模式
迭代器模式 要解决的问题 迭代器要解决的问题很简单很单纯,就是进行遍历操作. 实现原理 基本所有语言都实现了迭代器,javascript也不例外,如Array.prototype.forEach,fo ...
- 迭代器模式(Iterator Pattern)
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式(Iterator)就是分离了聚合对象的遍历行为,抽象出一个迭代器来负责这样既可以 ...
随机推荐
- mysql5.6中 order by 多个字段排序问题
今天用order by排序 后面跟了多个字段,如sql语句: SELECT a.id,a.loginname,a.address,u.id,u.`name`,u.address FROM admin_ ...
- GZFramwork快速开发框架之窗体设计说明
1. 明细页数据源获取(基类已经处理) 重载GetEditData方法,此方法为自定义获得明细也的数据源,用于绑定明细页,此返回值会赋值给EditData //根据主键获得数据编辑页的数据 publ ...
- C语言面试题(二)
上篇对嵌入式中C语言基本数据类型,关键字和常用操作进行了汇总,这篇我们将侧重字符串操作.请看下面的字符串处理函数: a.库函数 1)将字符串src拷贝到字符数组dest内 c ...
- C#:类和结构的区别
第一.引用类型和值类型 类属于引用类型,而结构属于值类型. 结构在赋值时进行复制. 将结构赋值给新变量时,将复制所有数据,并且对新副本所做的任何修改不会更改原始副本的数据. 第二.继承性 类可以继承类 ...
- spring+mongo
一.程序结构
- html5常见问题
H5项目常见问题汇总及解决方案 2016-12-21 FrontEndZQ JavaScript 转自 https://github.com/FrontEndZQ/HTML5-FAQ H5项目常见问题 ...
- putty自动登录
如果没有公钥/密钥对,就用 PuTTYgen 创建一个,已经有了就可以忽略这一步.一个公钥/密钥对可以用在不同的服务器上,所以也不需要重复创建,关键要有足够强健的密码和安全的存放. 象先前一样输入帐户 ...
- 使用WIC组件转换图片格式
#include <windows.h>#include <Wincodec.h>#pragma comment(lib, "Windowscodecs.lib&qu ...
- 使用ueditor中的setContent() 时经常报innerHtml错误(笔记)
1)今天遇到个问题,使用ueditor中的setContent() 时经常报innerHtml错误:网上找了下解决方案:发现这个可以用: 不能创建editor之后马上使用ueditor.setCont ...
- 自定义控件之 RadioList
var RadioListObj = function (id, url) { this.URL = url;//radiobox source URL this.ID = id;//radioLis ...