首先,先说说iterator的定义。
iterator模式:提供一种方法,使之能够依序巡防某个容器所含的各个元素,而又无需暴露改容器的内部表达方式。
STL的中心思想在于:将数据容器和算法分开,彼此独立设计。然后再将其撮合在一起。容器和算法的泛型化。
下面的代码是STL里面find函数的实现代码
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <iostream>
using namespace std;
namespace TEST
{
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
{
while(first != last && *first != value)
{
++first;
}
return first;
}
}
int main()
{
const int arraySize = 7;
int ia[arraySize] = {0, 1, 2, 3, 4, 5, 6};
vector<int> ivect(ia, ia + arraySize);
list<int> ilist(ia, ia + arraySize);
deque<int> ideque(ia, ia + arraySize);
vector<int>::iterator it1 = TEST::find(ivect.begin(), ivect.end(), 4);
if (it1 == ivect.end())
{
cout << "4 not found." << endl;
}
else
{
cout << "4 found." << *it1 << endl;
}
list<int>::iterator it2 = TEST::find(ilist.begin(), ilist.end(), 6);
if (it2 == ilist.end())
{
cout << "6 not found." << endl;
}
else
{
cout << "6 found." << *it2 << endl;
}
deque<int>::iterator it3 = TEST::find(ideque.begin(), ideque.end(), 8);
if (it3 == ideque.end())
{
cout << "8 not found." << endl;
}
else
{
cout << "8 found." << *it3 << endl;
}
return 0;
};
这段代码虽然很简单。但是也从本质的说明了我们常用的find函数的实现。
迭代器是一种智能指针
迭代器是一种行为类似指针的对象。智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。
使用迭代器总结:
#include <iostream>
#include <vector>
#include <map>
#include <stdio.h>
using namespace std;
int main()
{
int data[7] = {1, 2, 3, 4, 5, 6, 7};
/*vector<int> m_vector(data, data + 7);
vector<int>::iterator it = m_vector.begin();*/
map<int, int> m_map;
for (int i = 0; i < 7; i++)
{
m_map[i] = i;
}
map<int, int>::iterator it = m_map.begin();
printf("%p\n", it);
it++;
printf("%p\n", it);
return 0;
}
it的地址没变。说明it++没有改变it的地址。也说明了,it++改变的是智能指针的计数器。通过改变计数器来达到遍历容器数据的目的。
下面介绍一下Traits编程技法。Traits编程技法是STL源代码的钥匙。
下面一段代码使用内嵌型声明方法。
#include <iostream>
using namespace std;
template <class T>
struct MyIter
{
typedef T value_type;
T* ptr;
MyIter(T* p = 0) : ptr(p){}
T& operator*() const {return *ptr;}
};
template <class I>
typename I::value_type
func(I ite)
{
return *ite;
}
int main()
{
MyIter<int> ite(new int(8));
cout << func(ite) << endl;
return 0;
};
上面这种方法可以帮我们得到 template情景下的返回值。
traits扮演的角色是“特性萃取机”角色。萃取各种迭代器的特性。这里的迭代器特性,指的是迭代器的相应型别。
特性萃取机能够有效运作,每一个迭代器必须遵守约定。
最常用的迭代器相应型别有五种:value type, difference type, pointer, reference, iterator catagoly。
迭代器相应型别之一:value type
所谓value type, 是指迭代器所指对象的型别。任何一个打算与STL算法有完美搭配的class,都应该定义自己的value type内嵌型别。
迭代器相应型别之二:difference type
difference tyoe用来表示两个迭代器之间的距离。因此也可以用来表示一个容器的最大容量,因为对于连续空间而言,头尾之间的距离
就是其最大容量。
迭代器相应型别之三:reference type
迭代器分为两种:不允许改变“所指对象之内容”和允许改变“所指对象之内容”。
迭代器相应型别之四:pointer type
pointers和references。就是在萃取器里面传回一个pointer,指向迭代器所指之物。
迭代器相应型别之五:iterator_category
根据移动特性与施行操作,迭代器被分为五类。
intput iterator:只能读的迭代器。
output iterator:只能写的迭代器。
forward iterator:允许写入型算法。
bidirectional Iterator:可双向移动。
random access iterator:蕴涵所有指针算术能力。
#pragma once
#include <iostream>
using namespace std;
struct B
{
};
struct D1 : public B
{
};
struct D2 : public D1
{
};
template <class T>
func(T& p, B)
{
cout << "B version" << endl;
}
template <class T>
func(T& p, D2)
{
cout << "D2 version" << endl;
}
有template的文件必须在*.h里面,要不然会出错。
int main()
{
int p;
func(p, B());
func(p, D1());
func(p, D2());
return 0;
};
输出结果是
上述代码必须排除error4430才行。
这段代码主要说明了,类和继承的关系。
总结:设计适当的相应型别,是迭代器的责任。设计适当的迭代器,则是容器的责任。
taits编程技法大量运用于STL实现品中。它利用内嵌型别的编程技巧与编译器的template参数推导功能。增强
C++未能提供的关于型别认证方面的能力。弥补不为强型别语言的遗憾。
汗,还是照本宣科。上面部分是我看得懂的。希望对大家有帮助。