STL迭代器(iterator)

来源:互联网 发布:如何注册多个淘宝小号 编辑:程序博客网 时间:2024/06/10 08:27

迭代器定义

迭代器(iterator):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。共有5种类型

迭代器模式:提供一种方法,使之能够依序寻访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。

STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂(iterator)将它们撮合在一起。

STL的迭代器是一个可遍历STL容器全部或者部分数据。

迭代器原理

迭代器是一种行为类似智能指针的对象,而指针最常见的行为就是内容提领和成员访问。因此迭代器最重要的行为就是对operator*和operator->进行重载。

 迭代器的应用

#include <iostream>#include <vector>#include <list>#include <algorithm>#include <string>using namespace std;void Test1(){vector<int > v1;v1.push_back(5);v1.push_back(4);v1.push_back(3);v1.push_back(2);v1.push_back(1);// 迭代器遍历顺序表vector<int >::iterator it = v1.begin();for (; it != v1.end(); ++it){cout << *it << " ";}cout << endl;// STL的排序算法sort(v1.begin(), v1.end());it = v1.begin();for (; it != v1.end(); ++it){cout << *it << " ";}cout << endl;}void Test2(){list<string > l1;l1.push_back("xjh");l1.push_back("zpw");l1.push_back("yb");l1.push_back("whb");// 迭代器遍历链表list<string >::iterator it = l1.begin();for (; it != l1.end(); ++it){cout << *it << " ";}cout << endl;// STL的替换算法replace(l1.begin(), l1.end(), "xjh", "lcf");it = l1.begin();for (; it != l1.end(); ++it){cout << *it << " ";}cout << endl;}void Test3(){list<string > l1;l1.push_back("xjh");l1.push_back("zpw");l1.push_back("yb");l1.push_back("whb");// 迭代器遍历链表list<string >::iterator it = l1.begin();for (; it != l1.end(); ++it){cout << *it << " ";}cout << endl;// STL的find 算法查找迭代器区间的数据,并返回找到节点的迭代器it = find(l1.begin(), l1.end(), "yb");if (it != l1.end()){cout << "find success:" << *it << endl;// 通过迭代器修改节点数据*it = "yls";}it = find(l1.begin(), l1.end(), "yb");if (it == l1.end()){cout << "find failed" << endl;}}

迭代器失效

由删除导致,指向当前节点的迭代器被删除

解决办法:1、保存当前位置,指向下一个迭代器。2、用一个接收erase的返回值。

#include<iostream>using namespace std;#include<vector>#include<list>void PrintVector(vector<int>& v){vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;}void PrintList(list<int>& l){list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}cout << endl;}void TestVector(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);PrintVector(v);vector<int>::iterator it = v.begin();while (it != v.end()){//迭代器失效vector<int>::iterator tmp = it;++it;if ((*tmp) % 2 == 0){v.erase(tmp);}(*it)++;cout << *it << " ";++it;}cout << endl;}void TestList(){list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);PrintList(l);list<int>::iterator it = l.begin();while (it != l.end()){//迭代器失效/*list<int>::iterator tmp = it;++it;if ((*tmp) % 2 == 0){l.erase(tmp);}*///迭代器失效if ((*it) % 2 == 0){it=l.erase(it);}else{++it;}(*it)++;cout << *it << " ";++it;}cout << endl;}
迭代器的型别和类型萃取技术



#pragma once //迭代器型别struct InputIteratorTag {};struct OutputIteratorTag {};struct ForwordIteratorTag : public InputIteratorTag {};struct BidirectionalIteratorTag : public ForwordIteratorTag {};struct RandomAccessIteratorTag : public BidirectionalIteratorTag {};template <class T, class Distance> struct InputIterator {typedef InputIteratorTag IteratorCategory;typedef T                  ValueType;typedef Distance           DifferenceType;typedef T*                 Pointer;typedef T&                 Reference;};struct OutputIterator {typedef OutputIteratorTag IteratorCategory;typedef void                ValueType;typedef void                DifferenceType;typedef void                Pointer;typedef void                Reference;};template <class T, class Distance> struct ForwardIterator {typedef ForwordIteratorTag IteratorCategory;typedef T                    ValueType;typedef Distance             DifferenceType;typedef T*                   Pointer;typedef T&                   Reference;};template <class T, class Distance> struct BidirectionalIterator {typedef BidirectionalIteratorTag IteratorCategory;typedef T                          ValueType;typedef Distance                   DifferenceType;typedef T*                         Pointer;typedef T&                         Reference;};template <class T, class Distance> struct RandomAccessIterator{typedef RandomAccessIteratorTag IteratorCategory;typedef T                          ValueType;typedef Distance                   DifferenceType;typedef T*                         Pointer;typedef T&                         Reference;};//// 迭代器内嵌包含的种相应的型别// IteratorCategory 、ValueType、 DifferenceType、Pointer、 Reference// 这种内嵌的型别定义,确保了能够更方便的跟 STL融合。// 且方便IteratorTraits的类型萃取//template <class Category, class T, class Distance = ptrdiff_t,class Pointer = T*, class Reference = T&>struct Iterator {typedef Category  IteratorCategory;// 迭代器类型typedef T         ValueType;// 迭代器所指对象类型typedef Distance  DifferenceType;// 两个迭代器之间的距离typedef Pointer   Pointer;// 迭代器所指对象类型的指针typedef Reference Reference;// 迭代器所指对象类型的引用};//Traits 就像一台 “ 特性萃取机 ” ,榨取各个迭代器的特性(对应的型别)template <class Iterator>struct IteratorTraits {typedef typename Iterator::IteratorCategory IteratorCategory;typedef typename Iterator::ValueType        ValueType;typedef typename Iterator::DifferenceType   DifferenceType;typedef typename Iterator::Pointer           Pointer;typedef typename Iterator::Reference         Reference;};/// 偏特化原生指针类型template <class T>struct IteratorTraits<T*> {typedef RandomAccessIteratorTag IteratorCategory;typedef T                          ValueType;typedef ptrdiff_t                  DifferenceType;typedef T*                         Pointer;typedef T&                         Reference;};/// 偏特化const原生指针类型template <class T>struct IteratorTraits<const T*>{typedef RandomAccessIteratorTag IteratorCategory;typedef T                          ValueType;typedef ptrdiff_t                  DifferenceType;typedef const T*                   Pointer;typedef const T&                   Reference;};//Distance的实现template <class InputIterator>inline typename IteratorTraits<InputIterator>::DifferenceType__Distance(InputIterator first, InputIterator last,InputIteratorTag) {IteratorTraits<InputIterator>::DifferenceType n = 0;while (first != last) { ++first; ++n; }}template <class RandomAccessIterator>inline typename IteratorTraits<RandomAccessIterator>::DifferenceType__Distance(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIteratorTag){return last - first;}template <class InputIterator>inline typename IteratorTraits<InputIterator>::DifferenceTypeDistance(InputIterator first, InputIterator last) {return __Distance(first, last, IteratorTraits<InputIterator>::IteratorCategory());}//Advance的实现template <class InputIterator, class Distance>inline void __advance(InputIterator& i, Distance n, InputIteratorTag){while (n--) ++i;}template <class BidirectionalIterator, class Distance>inline void __Advance(BidirectionalIterator & i, Distance n,BidirectionalIteratorTag){if (n >= 0)while (n--) ++i;elsewhile (n++) --i;}template <class RandomAccessIterator, class Distance>inline void __Advance(RandomAccessIterator & i, Distance n,RandomAccessIteratorTag){i += n;}template <class InputIterator, class Distance>inline void Advance(InputIterator & i, Distance n){__Advance(i, n, IteratorTraits <InputIterator>::IteratorCategory());}template <class T, class Distance>inline T* ValueType(const InputIterator<T, Distance>&) {return (T*)(0);}/////////////////////////////////////////template <class T, class Distance>inline T* ValueType(const ForwardIterator<T, Distance>&) {return (T*)(0);}template <class T, class Distance>inline T* ValueType(const BidirectionalIterator<T, Distance>&) {return (T*)(0);}template <class T, class Distance>inline T* ValueType(const RandomAccessIterator<T, Distance>&) {return (T*)(0);}template <class T>inline T* ValueType(const T*) { return (T*)(0); }//////////////////////////////////////////////////////////////////////// 逆置迭代器的定义,反向迭代器是正向迭代一层封装template <class Iterator>class ReverseIterator{public:// 通过迭代器萃取器,萃取出正向迭代器中定义的基本类型typedef typename IteratorTraits<Iterator>::IteratorCategory IteratorCategory;typedef typename IteratorTraits<Iterator>::ValueType        ValueType;typedef typename IteratorTraits<Iterator>::DifferenceType   DifferenceType;typedef typename IteratorTraits<Iterator>::Pointer          Pointer;typedef typename IteratorTraits<Iterator>::Reference        Reference;typedef Iterator IteratorType;typedef ReverseIterator<Iterator> Self;public:ReverseIterator() {}explicit ReverseIterator(IteratorType x): _current(x){}Reference operator*() const{// 注意这里解引用时取的是当前位置的前一个数据。// 以为RBegin()==End() REnd()==Begin() Iterator tmp = _current;return *--tmp;}Pointer operator->() const{return &(operator*());}Self& operator++() {--_current;return *this;}Self operator++(int){Self tmp = *this;--_current;return tmp;}Self& operator--() {++_current;return *this;}Self operator--(int) {Self tmp = *this;++_current;return tmp;}bool operator != (const Self& x) {return _current != x._current;}protected:Iterator _current;};


0 0
原创粉丝点击