迭代器定义
迭代器(iterator):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。共有5种类型
迭代器模式:提供一种方法,使之能够依序寻访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。
STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂(iterator)将它们撮合在一起。
STL的迭代器是一个可遍历STL容器全部或者部分数据。
迭代器原理
迭代器是一种行为类似智能指针的对象,而指针最常见的行为就是内容提领和成员访问。因此迭代器最重要的行为就是对operator*和operator->进行重载。
迭代器的应用
#include
#include
#include
#include
#include
using namespace std;
void Test1()
{
vector v1;
v1.push_back(5);
v1.push_back(4);
v1.push_back(3);
v1.push_back(2);
v1.push_back(1);
// 迭代器遍历顺序表
vector::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 l1;
l1.push_back("xjh");
l1.push_back("zpw");
l1.push_back("yb");
l1.push_back("whb");
// 迭代器遍历链表
list::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 l1;
l1.push_back("xjh");
l1.push_back("zpw");
l1.push_back("yb");
l1.push_back("whb");
// 迭代器遍历链表
list::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
using namespace std;
#include
#include
void PrintVector(vector& v)
{
vector::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void PrintList(list& l)
{
list::iterator it = l.begin();
while (it != l.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void TestVector()
{
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
PrintVector(v);
vector::iterator it = v.begin();
while (it != v.end())
{
//迭代器失效
vector::iterator tmp = it;
++it;
if ((*tmp) % 2 == 0)
{
v.erase(tmp);
}
(*it)++;
cout << *it << " ";
++it;
}
cout << endl;
}
void TestList()
{
list l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
PrintList(l);
list::iterator it = l.begin();
while (it != l.end())
{
//迭代器失效
/*list::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
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 struct ForwardIterator
{
typedef ForwordIteratorTag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
};
template struct BidirectionalIterator
{
typedef BidirectionalIteratorTag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
};
template 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
struct Iterator
{
typedef Category IteratorCategory;// 迭代器类型
typedef T ValueType;// 迭代器所指对象类型
typedef Distance DifferenceType;// 两个迭代器之间的距离
typedef Pointer Pointer;// 迭代器所指对象类型的指针
typedef Reference Reference;// 迭代器所指对象类型的引用
};
//Traits 就像一台 “ 特性萃取机 ” ,榨取各个迭代器的特性(对应的型别)
template
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
struct IteratorTraits
{
typedef RandomAccessIteratorTag IteratorCategory;
typedef T ValueType;
typedef ptrdiff_t DifferenceType;
typedef T* Pointer;
typedef T& Reference;
};
/// 偏特化const原生指针类型
template
struct IteratorTraits
{
typedef RandomAccessIteratorTag IteratorCategory;
typedef T ValueType;
typedef ptrdiff_t DifferenceType;
typedef const T* Pointer;
typedef const T& Reference;
};
//Distance的实现
template
inline typename IteratorTraits::DifferenceType
__Distance(InputIterator first, InputIterator last,InputIteratorTag)
{
IteratorTraits::DifferenceType n = 0;
while (first != last)
{
++first;
++n;
}
}
template
inline typename IteratorTraits::DifferenceType
__Distance(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIteratorTag)
{
return last - first;
}
template
inline typename IteratorTraits::DifferenceType
Distance(InputIterator first, InputIterator last)
{
return __Distance(first, last, IteratorTraits::IteratorCategory());
}
//Advance的实现
template
inline void __advance(InputIterator& i, Distance n, InputIteratorTag)
{
while (n--)
++i;
}
template
inline void __Advance(BidirectionalIterator & i, Distance n,BidirectionalIteratorTag)
{
if (n >= 0)
while (n--) ++i;
else
while (n++) --i;
}
template
inline void __Advance(RandomAccessIterator & i, Distance n,RandomAccessIteratorTag)
{
i += n;
}
template
inline void Advance(InputIterator & i, Distance n)
{
__Advance(i, n, IteratorTraits ::IteratorCategory());
}
template
inline T* ValueType(const InputIterator&) {
return (T*)(0);
}
/////////////////////////////////////////
template
inline T* ValueType(const ForwardIterator&) {
return (T*)(0);
}
template
inline T* ValueType(const BidirectionalIterator&) {
return (T*)(0);
}
template
inline T* ValueType(const RandomAccessIterator&) {
return (T*)(0);
}
template
inline T* ValueType(const T*) { return (T*)(0); }
//////////////////////////////////////////////////////////////////////
// 逆置迭代器的定义,反向迭代器是正向迭代一层封装
template
class ReverseIterator
{
public:
// 通过迭代器萃取器,萃取出正向迭代器中定义的基本类型
typedef typename IteratorTraits::IteratorCategory IteratorCategory;
typedef typename IteratorTraits::ValueType ValueType;
typedef typename IteratorTraits::DifferenceType DifferenceType;
typedef typename IteratorTraits::Pointer Pointer;
typedef typename IteratorTraits::Reference Reference;
typedef Iterator IteratorType;
typedef ReverseIterator 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;
};