STL 源码剖析
源码推荐读SGI STL
源码,可以自行下载
这里我从容器开始看起,不要太关注allocator
和Iterators
等细节,而去关注数据结构和算法的实现。
学习完一遍容器后再回来学。
STL 六大组件的交互关系:容器通过配置器取得数据存储空间,算法通过迭代器存取容器内容,仿函数可以协助算法完成不同的策略变化,配接器可以修饰或套接仿函数。
容器
容器分为序列式容器和关联器容器
序列式容器
所谓序列式容器,其中的元素都可序,但未必有序。
vector
vector
与array
非常相似。array
是静态空间,一旦配置了就不能改变;如果满了想换个更大的,首先要配置一块新空间,然后将元素从旧址一一搬往新地址,再把原来的空间释放给系统。vector
是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素。
- vector 与 array 唯一区别是空间的运用的灵活性。
- array 是静态空间,一旦配置了就不能改变。
- vector 维护的是一个连续线性空间,所以不论其元素类型为何,普通指针都可以作为 vector 的迭代器而满足所有必要条件。
- 增加新元素,如果超过当时的容量,则容量会扩充至两倍。
- <stl_vector.h> 会调用 <stl_bvector.h> 的函数。
vector 上的常见操作复杂度
- 随机访问——常数 O(1)
- 在末尾插入或移除元素——均摊常数 O(1)
- 插入或移除元素到 vector 结尾的距离成线性 O(n)
vector
的迭代器涵盖了指针所有的算术能力(operator*,operator->,operator++,operator--,operator+,operator-,operator+=,operator-=
),
同时 vector 支持随机存取,所以 vector 提供是 Random Access
Iterator。
平时我们使用vector
时,声明如下:
1 | std::vector<int> vec0; |
那么它们是如何在源码中定义的,我们看下源码。
1 |
|
可以看到vector
是继承_Vector_base
vec0 是通过默认构造函数进行初始化,vec1通过_Vector_base(const _Alloc&)来初始化为0,vec2则先初始化为0,然后再赋值
基本函数实现
** 1. 构造函数**
vector()
:创建一个空的vector
vector(int nSize)
:创建一个vector
,元素个数为nSize
vector(int nSize, const t& t)
:创建一个vector
,元素个数为nSize
,且值均为t
vector(const vector&)
:复制构造函数vector(begin, end)
:复制[begin, end]
区间内另一个数组的元素到vector
中
1 | // 构造拥有 n 个有值 value 的元素的容器 |