本周开始,我们进入到了第三个课程内容的学习中——《STL与泛型编程》。
STL全名是标准模板库(Standard Template Library)。它与C++标准库(C++ Standard Library)的不同在于,模版库里面主要用到的是泛型编程(Generic Programming)的方式,主要都是用模板来实现的一些功能。而标准库都给定了需要的数据类型。
本周内容就是着重探索模版库中的那些细节来的。模版库对于C++来说是非常有用的一个仓库。里面包含了六大部件,分别是 容器,分配器,算法,迭代器,适配器,和仿函数。经典的面向对象编程会设计成为是 数据和算法 打包在一起。但是泛型编程不然,将数据和算法分开设计。需要使用的时候再由使用者根据需要自己选取。
对模版库开始接触是从容器开始,在这之前,了解一下,C++的模版库的容器都是采用的是前闭后开的区间形式。在C++ 11中加入了auto关键字以及新式的for loop语法,可以方便的合用来减小代码输入量。
容器
从类型分,容器可分为2种
- 顺序容器
- 关联性容器
这是侯爷的划分。
但讲义上给定的划分方式,将关联性容器又分了2种。
- 关联性容器
- 无序容器(具体表现形式,就是哈希表中采用的独立链)
接着,从STL中的几个典型的容器,我们分别看到了若干个测试代码,每个测试代码对应一个容器类型
于是我们一共看到了
- array
- vector
- deque
- list
- forward-list
- slist
- stack
- queue
- multiset
- multimap
- unordered_multiset
- unordered_multimap
- set
- map
- unordered_set
- unordered_map
这里有如此多的示例代码和容器的测试,在此不宜一一冗述。
他们的主要区别和关联在于array是固定大小的,分配内存之后,array就不能再变化内存空间了。
vector、deque、stack、queue都是一维顺序的可变大小的容器。不同在于他们的元素插入位置以及内存增加方向是不同的。
list和forward-list分别是双向链表和单向链表,都是C++ 11标准库里带有的容器。这里面,单向链表实际上是GNU C++ Compiler在之前非标准库中实现的一种单向链表的slist的标准化。他们在内存中是通过指针来串联起来的,内存空间是不连续的。
接下来set和map是两种基于红黑树内存结构的容器,一个直译“集合”,一个是“映射”。他们有python字典的意味,他们都有自己的key跟value。对于set容器,key就是value;而对于映射,可以从任意类型的key映射到任意类型的value。set和map中单个key对应的元素只能够存放一个的。如果要放置key相同的多个元素怎么办,那就可以采用multiset和multimap了。
对于无序的容器,简单的从外部函数输出结果中查看了一下它的内存结构。测试的容器是unordered_set。对于无序容器,大多采用独立链形式来存储,容器是由一串篮子(bucket)组成的,每个篮子后面跟着一个链表,链表上存储的是他的元素。为了保障容器搜索元素和排序的效率,篮子的个数一定比容器所存储的元素个数要多。这也可以从测试代码的输出结果中看到。因此,必然的,很多篮子上的元素个数实际上是为零的。
分配器
最后,简单介绍了一下,六大部件中的分配器。