组件 | 描述 |
---|---|
容器(Containers) | 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 |
算法(Algorithms) | 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 |
迭代器(iterators) | 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。 |
容器
容器 | 特征 | 内存结构 | 可随机存取 | 元素搜寻速度 | 头文件 |
---|---|---|---|---|---|
vector | 在序列尾部进行插入和删除,访问和修改元素的时间复杂度为O(1),但插入和删除的时间复杂度与到末尾的距离成正比。 | 单端数组 | 可以 | 慢 | <vector> |
list | 对任意元素的访问与两端的距离成正比,但对某个位置的插入和删除花费为常数时间,即O(1) | 双向链表 | 否 | 非常慢 | <list> |
deque | 与vector基本相同,唯一不同的是,在序列头部插入和删除的时间复杂度也是O(1) | 双端数组 | 可以 | 慢 | <deque> |
set | 由节点组成的红黑树,具有快速查找的功能 | 二叉树 | 否 | 快 | <set> |
multiset | 可以支持重复元素,同样具有快速查找能力 | 二叉树 | 否 | 快 | <set> |
map | 由{键,值}对组成的集合,同样具有快速查找能力 | 二叉树 | 对key而言可以 | 对key而言快 | <map> |
multimap | 一个键可以对应于多个值,同样具有快速查找能力 | 二叉树 | 否 | 对key而言快 | <map> |
算法
算法是用来操作容器中数据的模板函数,它抽象了对数据结构的操作行为。要使用STL中定义的算法,应首先引入<algorithm>
头文件。例如STL中的sort()函数可以对容器中的数据进行排序,可以使用find()函数来搜索容器中的某个元素。这里的算法可以与C#中泛型方法进行对比来理解。
迭代器
STL实现要点是将容器和算法分开,使两者彼此独立。迭代器使两个联系起来,迭代器提供访问容器中的方法。迭代器实质上是一种智能指针,它重载了->和*操作符。事实上,C++指针也是一种迭代器。在C#中同样有迭代器的概念,具体参考MSDN.aspx),不同的是,在C++ 中迭代器分为五类,这五类分别为:
- 输入迭代器(Input Iterator)——提供对数据的只读访问;
- 输出迭代器(Output Iterator)——提供对数据的只写访问;
- 前推迭代器(Forward Iterator)——提供对数据的读写操作,并能向前推进的迭代器;
- 双向迭代器(Bidirectional Iterator)——提供对数据的读写操作,并能向前和向后操作;
- 随机访问迭代器(Random Access Iterator)——提供对数据的读写操作,并能在数据中随机移动。
函数对象
函数对象,又称为仿函数,STL中的函数对象就是重载了运算符()的模板类的对象,因为该类对象的调用方式类似与函数的调用方式,所以称为函数对象.
适配器
适配器是用来修改其他组件接口,与设计模式中的适配器模的达到的效果是一样的。STL中定义了3种形式的适配器:容器适配器、迭代器适配和函数适配器
- 容器适配器——包括栈(stack)、队列(queue)和优先队列(priority_queue),容器适配器是对基本容器类型进行进一步的封装,从而转换为新的接口类型。
- 迭代器适配器——对STL中基本迭代器的功能进行扩展,该类适配器包括反向迭代器、插入迭代器和流迭代器。
- 函数适配器——通过转换或修改来扩展其他函数对象的功能。该类适配器有否定器、绑定器和函数指针适配器。函数对象适配器的作用就是使函数转化为函数对象,或将多参数的函数对象转换为少参数的函数对象,如STL中bind2nd()就是绑定器。
空间配置器
当容器中保存的是用户自定义类型数据时,有的数据类型结构简单,占用的空间很小,而有的数据类型结构复杂,占用的内存空间较大;并且有的应用程序需要频繁地进行数据的插入删除操作,这样就需要对内存空间进行频繁地申请和释放工作,然而对内存的频繁操作,会产生严重的性能问题,为了解决这个问题,STL中提供了两个空间配置器,一个是简单空间配置器,仅仅对C运行库中malloc和free进行了简单的封装操作,另一个是“基于内存池的控件配置器”,即容器在每次申请内存的时候,内存池会基于一定的策略,向操作系统申请交大的内存空间,从而避免每次都向OS申请内存。STL中的空间配置器就是负责内存的分配和释放的工作