STL(标准模板库):一个泛型程序库
六大组件:
1 容器:各种数据结构,用于存放数据,管理某类对象的集合
1.1 序列式容器(Sequence container):为可序(ordered群集),每个元素有固定位置,位置取决于插入时机和地点,和元素值无关;
1.1.1 vector:向量,动态数组,可随机存取,即可以利用索引值直接存取任何一个元素,有下标存取值操作;
1.1.2 deque:双端队列,动态数组,可随机存取,即可以利用索引值直接存取任何一个元素,有下标存取值操作;
1.1.3 list:实际为双向链表,解决上面两种序列式容器在任意位置上插入或删除操作的耗时问题,但list不提供随机存取,因此也没有operator[ ]的下标存取操作;
除此之外,也可以把string以及array(数组)也当做序列式容器;
1.2 关联式容器(Associative container):为已序(sorted)群集,元素文职取决于特定的排序准则,元素位置取决于元素值,和插入次序无关,可当做特殊的序列式容器;
1.2.1 set:每个元素只能出现一次,不允许重复
1.2.2 multiset:与set相同,只是multiset允许重复元素的存在,即multiset可包含多个数值相同的元素;
1.2.3 map:map元素都是(key/value)对,每个元素都有一个键,排序是按照键进行排序,不是按照元素值排序,map的每一个键只允许出现一次,不允许重复,map可视为关联式数组,也就是具有任意索引型别的数组;[配合pair结构体使用],注意map允许使用operator[ ]存取元素;
1.2.4 multimap:与map相同,但multimap允许键值重复,即multimap可包含多个键值相同的元素;multiset可被当做“字典”;【配合pair结构体使用】,注意:multimap不允许使用operator[ ]操作符,因为multimap允许单一索引对应到多个元素,而下标操作符却只能处理单一实值;
排序准则以函数形式呈现,用来比较元素值(value)或元素键值(key),缺省情况下以operator<进行比较排序;该类容器通常由二叉树为底层原理实现;
1.3 容器配接器(Container Adapter):根据基本容器的实作提供的用于满足特殊场景或需求的容器;
1.3.1 stack:栈,采用LIFO管理策略
1.3.2 queue:采用FIFO管理策略,是个普通的缓冲区(buffer)
1.3.3 priority_queue:该容器中的元素可以拥有不同的优先权,优先权是基于排序准则的,缺省使用operator<,因此queue相当于“下一个元素永远是queue中优先级最高的元素”的buffer,注意如果同时有多个元素具备最高优先权,则其次序无明确定义;
也可当做特殊的序列式容器
2 算法
STL算法是一种function template;
3 迭代器
可遍历STL容器内全部或部分元素的对象,一个迭代器用来指出容器中的一个特定位置,扮演容器与算法之间的胶合剂,属于“泛型指针”,重载了operator* , operator->, operator++,operator–等指针操作;原生指针也是一种迭代器;
基本操作
a: operator*
b: operator++:注意:建议使用++it这种前置式的递增,因为后置式的递增it++会需要一个额外的临时对象,所以一般情况下建议使用++it,而不是用it++;
c: operator== operator!=
d: operator=
e: begin():返回一个迭代器,指向容器起始点,即第一个元素(如果有的话)的位置;
begin()与end()形成的是一个形如[ )的区间,如上图;不必对空区间采取特殊处理,空区间的begin()就等于end();
f: end():返回一个迭代器,指向容器结束点,结束点在最后一个元素之后,即刚好超出容器的范围的第一个位置;
注意:任何一种容器都定义了两种迭代器型别:
1: container::iterator:以“读/写”模式遍历元素”
2: container::const_iterator:以“只读”模式遍历元素;
STL容器中预定义好的迭代器分类
双向迭代器:以递增前进,以递减后退,list, set, multiset, map, multimap这些容器所提供的迭代器属于此类;
随机存取迭代器:具备双向迭代器的所有属性,还具有随机访问能力,可以对迭代器增加或减少一个偏移量,处理迭代器之间的距离,或是使用<和>之类的比较关系运算符来比较两个迭代器,vector,deque,string所提供的迭代器都属于此类;
注意:建议为了撰写尽可能与容器型别无关的泛型代码,最好不要使用随机存取迭代器的特有操作如<等比较运算符;
迭代器被划分为5种不同类属,以上是STL中预定义好的迭代器分类;
4仿函数
实际是一种重载了operator()的类或模板类
5配接器
用来修饰容器,或仿函数,或迭代器接口的东西,即容器分类上面的容器配接器
6配置器
负责空间配置与管理,实现了动态空间配置,空间管理,空间释放的class template
注意:STL的设计原则是效率优先,安全次之,错误检查几乎没有,对于STL的任何运用,如果违反规则,将会导致未定义行为,因此使用STL,必须满足以下要求:
1 迭代器务必合法有效;
2 对逾尾的迭代器不进行operator*或operator->;
3 区间必须合法:包括:
3.1 指示两个区间的迭代器必须是指向统一容器;
3.2 从第一个迭代器出发,必须可以到达第二个迭代器;
3.3 如过一个函数中涉及的区间不止一个,第二区间及后继区间必须拥有“至少和第一区间一样多”的元素;
3.4 覆盖动作中的目标区间,必须拥有足够元素,否则就必须采用insert iterators(插入型迭代器);
参考资料:《c++标准程序库》 侯捷/孟岩 译