STL,即标准模板库(Standard Template Library),是一些常用数据结构和算法模板的集合,主要由6大组成部分组成。
容器(Container)
是一种数据结构, 如list, vector, 和deques,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器。
算法(Algorithm)
是用来操作容器中的数据的模板函数。例如,STL用sort()来对一 个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以用于从简单数组到高度复杂容器的任何数据结构上。
迭代器(Iterator)
提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。 迭代器就如同一个指针。事实上,C++ 的指针也是一种迭代器。 但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符方法的类对象;
仿函数(Function object)
仿函数又称之为函数对象, 本质就是重载了operator()的类。
适配器(Adaptor)
简单的说就是一种接口类,专门用来修改现有类的接口,提供一种新的接口,或调用现有的函数来实现所需要的功能。主要包括3中适配器Container Adaptor、Iterator Adaptor、Function Adaptor。
空间配制器(Allocator)
为STL提供空间配置的系统。其主要工作包括两部分:
对象的创建与销毁;
内存的获取与释放。
数据结构:动态数组
特点:
resize和reserve的区别:
reserve(n)是预留n个元素的空间,如果n大于当前的capacity,则开辟一块更大的空间以容纳至少n个元素。但是,对于多出来的这些空间,reserve不会对他们进行初始化,对这些区域的访问是非法的。resize(n,val)修改的是容器当前的size。如果n数据结构:双向链表
特点:
数据结构:双端队列(Double End Queue)
deque的中控器存储每个内存块的指针,每个内存块的
cur记录当前数据的位置,first和last记录内存块的起始和末尾。
特点:
数据结构:红黑树
特点:
数据结构:红黑树
特点:
数据结构:哈希表
特点:
数据结构:栈,默认封装deque的接口,封装容器可根据传入的模板参数改变
特点:
数据结构:队列,默认封装deque的接口,封装容器可根据传入的模板参数改变
特点:
数据结构:堆,默认封装vector的接口,封装容器可根据传入的模板参数改变
特点:
对于顺序容器,如vector,删除前面的元素会导致后面元素的迭代器失效,但是可以通过erase获取到被删除元素的下一个元素的新迭代器。此外,增加元素可能会导致整个容器的扩容,从而使所有迭代器都失效。
对于list,由于是非顺序存储,因此增删一个节点不会使其他节点的迭代器失效。
对于deque,如果增加元素导致扩充,则会引起所有迭代器失效,因为迭代其内部有指向中控器的指针。其他情况下,对于头尾的插入删除,不会引起迭代器失效,但是对于中间元素的插入删除,会引起对应位置前或后的元素移动,具体哪些迭代器会失效根据当时的内存分布而定。
对于关联容器,如map/set/multimap/multiset,底层使用红黑树,是非顺序存储,所以增删一个节点不会使其它迭代器失效。但是它们的erase不会返回下一个节点的迭代器。
但是对于unordered_map/unordered_set,底层使用哈希表,增加节点可能会导致整个表的重映射,从而导致所有迭代器失效。
空间配置器是用来实现内存空间分配的工具,与容器联系紧密,每一种容器的空间分配都是通过空间分配器alloctor实现的。
空间配置器有两级结构,第一级用于处理128字节以上的大内存,其余小内存由第二级处理。
直接使用malloc和free向系统申请和释放内存。
维护了一个内存池,内存池中存有16种不同大小的内存块(128/8),用于适应不同的内存需求。