STL六大组件

容器(Container)

是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;

迭代器(Iterator)

提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象;

迭代器的作用:能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;常见的一些迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator.

算法(Algorithm)

是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;

算法部分主要由头文件,和组成。

STL中算法大致分为四类:

  • 非可变序列算法:指不直接修改其所操作的容器内容的算法。
  • 可变序列算法:指可以修改它们所操作的容器内容的算法。
  • 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
  • 数值算法:对容器内容进行数值计算。

仿函数(Functor)

我们通过在一个类中重载括号运算符的方法使用一个函数对象而不是一个普通函数。

要使用STL内建的仿函数,必须包含头文件

#include <iostream>
#include <algorithm>

using namespace std;
template<typename T>
class display
{
public:
void operator()(const T &x)
{
cout << x << " ";
}
};
int main()
{
int ia[] = { 1,2,3,4,5 };
for_each(ia, ia + 5, display<int>());
system("pause");
return 0;
}

适配器(Adaptor)

什么是容器适配器

”适配器是使一种事物的行为类似于另外一种事物行为的一种机制”,适配器对容器进行包装,使其表现出另外一种行为。例 如,stack >实现了栈的功能,但其内部使用顺序容器vector来存储数据。(相当于是vector表现出 了栈的行为)。

容器适配器

要使用适配器,需要加入一下头文件:

#include <stack>        //stack
#include<queue> //queue、priority_queue

分配器(allocator)

其实我们可以把allocator看成一个简易的内存池,其主要适用于在使用容器时,对内存空间的动态分配,如果是我们平常要申请一块动态内存时,不推荐使用allocator,应该使用new-delete(malloc-free),主要原因是allocator不好用(使用不方便,容器例外),在内存释放的时候还需要提供对象的个数,因为我们在动态分配内存时候基本上都是对指针所指向的内存空间进行操作,而不会去记录空间中构造了多少个对象。

#include <iostream>
#include <memory>
using namespace std;
//先熟悉一下提供的allocator用法
int main(int argc, char const *argv[])
{
allocator<int> a;
int *ptr=a.allocate(5);
a.construct(ptr,3);
a.construct(ptr+1,-3);
a.construct(ptr+2,3);
a.construct(ptr+3,-3);
a.construct(ptr+4,3);
for(int i=0;i<5;i++)
{
cout<<*(ptr+i)<<" ";
a.destroy(ptr+i);
}
a.deallocate(ptr,5);
return 0;
}

一个分配器中一定要有allocate、deallocate、construct、destroy四个函数,分别表示内存分配,内存释放、对象构造、对象析构。在一般的allocator中allocate直接是调用::operator new(),deallocate直接调用::operator delete(),没有什么性能上的优化。