STL从广义上讲分为三类: algorithm(算法) 、container(容器)、iterator(迭代器)。容器和算法可以通过迭代器进行无缝的连接。
在C++标准库中,STL被组织为下面的13个头文件:
STL六大组件:容器(container) 算法(algorithm) 迭代器(iterator) 仿函数(function object)
适配器(adaptor) 空间配置器(allocator)
使用STL的好处:
1)STL是C++的一部分,因此不用额外安装什么,它被内建在你的编译器之内。
2)STL的一个重要特点是数据结构和算法的分离。(内部使用的模板,或者说泛型编程)
3)程序员可以不用思考STL具体的实现过程,只要能够熟练使用STL。比精力用在开发上
4)STL具有高可重用性、高性能、高移植性、跨平台等优点
高可重用性: STL中几乎所有的代码的采用了模板类和模板函数的方式实现,这相当于传统的由函数和类组成的库来说提供了更好的代码重用机会。 高性能:底层使用的数据结构和算法比较优秀,如map的红黑树 高移植性:因为是内建在编译器之内,项目A中用STL编写的模块可以直接移植到项目B上。 跨平台:windows上写的可以在Linux上运行(反之一同)
5)每一个C++程序员都应该好好学习STL。只有熟练的使用STL的程序员,才是好C++程序员。
在实际开发过程中,数据结构本身的重要性不会逊色于操作于数据结构的算法的重要性。举个例子(二叉搜索数-->AVL-->红黑树-->BTREE-->B+TREE),不同的应用场景使用不同的数据结构。当程序中存在对时间要求很高的部分,数据结构的选择就显得更加重要。
经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码十分相似,只是为了适应不同数据的变化而在细节上有所出入。STL容器为我们提供了这样的方便。它允许我们重复利用已有的实现构造直接特定类型下的数据结构,通过设置一些模板,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型。
容器部分主要包括头文件:《vector》《list》《deque》《set》《map》《stack》《queue》
容器的概念:
用来管理一组元素(下图为逻辑上的理解)
容器的分类
序列式容器(sequence containers)
每一个元素都有固定位置:取决于插入时机和地点和元素值无关
vector deque list (vector和deque可能会造成迭代器实现)
关联式容器(associated containers)
元素的位置取决于特定的排序准则和插入顺序无关
set、multiset、map、multimap
数据结构 | 描述 | 头文件 |
向量(vector) | 连续存储的元素 | |
列表(list) | 由节点组成的双向链表,每一个节点对包含着一个元素 | |
双队列(deque) | 连续存储的指向不同元素的指针所组成的数组 | |
集合(set) | 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排序。 | |
多重集合(multiset) | 允许存在两个次序相等的元素的集合 | |
栈(stack) | 先进后出,一种特殊的线性表 | |
队列(queue) | 先进先出, 一种特殊的线性表 | |
优先队列(priority_queue) | 底层是堆的结构,元素的次序是由作用于所谓的值对上某种谓词决定的一种队列 | |
映射(map) | 由(键值)对组成的集合,以某种作用于键对上的谓词排序 | |
多重映射(multiset) | 允许键对有相等的次序的映射 |
迭代器从作用上来说是最基本的部分,理解起来有点难度。
软件设计有一个原则(或者说分层),所有的问题都可以通过引入一个间接层来简化。在STL中就是用迭代器完成的。概括的说,迭代器在STL中用来将算法和容器联系起来,起着一种粘合剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素进行工作的,每一个 容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
迭代器部分主要由头文件
组成。
utility 很小的头文件,包括了贯穿使用在STL中的几个模板声明 iterator 提供了迭代器,使用的许多方法 memory 为容器中的元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制。memory主要部分是模板类allocator,它负责产生所有容器中默认分配器。
函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数的情况下的可重用性肯定比使用整型作为参数高。而C++通过模板的机制允许推迟对某些类型的选择,直到正真想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了很多有用的算法。
STL提供了大约100个实现算法的模板函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你指定的规则对序列进行稳定排序。只要熟悉STL之后,许多代码可以被大大的简化,只需要通过调用一两个函数算法模板,就可以完成所需要的功能并大大地提升效率。
算法部分主要用由头文件
组成。 是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模板函数组成,可以认为每一个函数是独立的,其中常用的功能:比较、交换、查找、遍历、操作、复制、修改、移除 、反转、排序、合并等。 体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括假发和乘法在序列上的一些操作。 中则定义了一些模板类,用以声明函数对象 。
C++强大的功能来源于其丰富的类库及函数库资源(一门优秀的语言其库的强大是不可缺少的条件)。
在实际的开发过程中,要尽可能地利用标准库完成:
1.已经作为标准提供,减少开发成本
2.标准库都是经过严格测试的,正确性有保证
3.形成良好的编程风格
头文件 | 描 述 |
定义宏NULL和offsetof,以及其他标准类型size_t和ptrdiff_t | |
提供与基本数据类型相关的定义。定义了可以表示出来的最大值和最小值以及二进制数字的位数。 | |
提供与基本整数数据类型相关的C样式定义。 | |
提供与基本浮点型数据类型相关的C样式定义。 | |
提供支持程序启动和终止的宏和函数。另外,还要一些杂项函数 | |
支持动态内存分配 | |
支持变量在运行期间的类型标识 | |
支持异常处理,这是处理程序中可能发生的错误的一种方式 | |
支持接受数量可变的参数的函数。它定义了宏 va_arg、va_end、va_start、va_list类型 | |
为C样式的非本地跳跃提供函数。这些函数在C++中不常用 | |
为中断处理提供C样式支持 |
支持流输入/输出的头文件
头文件 | 描 述 |
支持标准流cin、cout、cerr和clog的输入输出,它还支持多字节字符标准流wcin、wcout、wcerr和wclog | |
改变输出格式 | |
定义iostream的基类 |
...其他头文件,不做详细介绍了
C++标准库的所有头文件都没有扩展名。C++标准库以