STL-05-vector使用及其源码剖析

vector 容器是 STL 中最常用的容器之一,它和 array 容器非常类似,都可以看做是对 C++ 普通数组的“升级版”。不同之处在于,array 实现的是静态数组(容量固定的数组),而 vector 实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector 会动态调整所占用的内存空间,整个过程无需人工干预。

vector 容器以类模板 vector( T 表示存储元素的类型)的形式定义在 头文件中,并位于 std 命名空间中。因此,在创建该容器之前,代码中需包含如下内容:

#include 
using namespace std;

下面将成员函数总结一下;

函数成员 函数功能
begin() 返回指向容器中第一个元素的迭代器。
end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的迭代器。
rend() 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() 返回实际元素个数。
max_size() 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
resize() 改变实际元素的个数。
capacity() 返回当前容量。
empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
reserve() 增加容器的容量。
shrink _to_fit() 将内存减少到等于当前元素实际所使用的大小。
operator[ ] 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
at() 使用经过边界检查的索引访问元素。
front() 返回第一个元素的引用。
back() 返回最后一个元素的引用。
data() 返回指向容器中第一个元素的指针。
assign() 用新元素替换原有内容。
push_back() 在序列的尾部添加一个元素。
pop_back() 移出序列尾部的元素。
insert() 在指定的位置插入一个或多个元素。
erase() 移出一个元素或一段元素。
clear() 移出所有的元素,容器大小变为 0。
swap() 交换两个容器的所有元素。
emplace() 在指定的位置直接生成一个元素。
emplace_back() 在序列尾部生成一个元素。

先看看侯捷的:
STL-05-vector使用及其源码剖析_第1张图片
这版本的是2倍增长。
迭代器是一个指针。

STL-05-vector使用及其源码剖析_第2张图片
STL-05-vector使用及其源码剖析_第3张图片

接下来看看vs2013
源码位置:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\vector

先看看它长啥样:
STL-05-vector使用及其源码剖析_第4张图片
可一看到元素类型 _Ty,还有分配器allocator,这个分配器,我博客有个分栏叫作内存管理,你看了就会懂。所以这个分栏里的剖析我都不会再讲分配器的知识。

剖析源码,首先得找重点,而我喜欢将插入作为切入点。

那就来看看吧:

STL-05-vector使用及其源码剖析_第5张图片
接下来看这个insert函数也就是这个函数真正实现了添加元素的功能。

其实插入分为三个分支,分别如下:
在这里插入图片描述

1)可用空间不足

在这里插入图片描述
代码如下:
STL-05-vector使用及其源码剖析_第6张图片

可用空间不足,就会重新申请空间,但申请多少,得有个规定,请看1669行,

在这里插入图片描述
找到_Grow_to()

STL-05-vector使用及其源码剖析_第7张图片

可以看到正常情况下是增长当前容器个数的50%。

下面做个试验:
STL-05-vector使用及其源码剖析_第8张图片
如结果所示,得到验证。

现在来看看插入的代码

STL-05-vector使用及其源码剖析_第9张图片

这个分为两部分讲:
1.将新的元素先拷贝进去。接着看源码

STL-05-vector使用及其源码剖析_第10张图片

代码意思就是,在新申请的内存第_whereoff的位置把新的添加上。

2.将原来插入位置前的位置所有的元素移动到新的空间。新的空间插入起始位置:首元素地址至刚插入的前一个位置
STL-05-vector使用及其源码剖析_第11张图片

3.将从插入位置到最后的元素插入到新的空间,新的空间插入起始位置:刚插入的下一个位置至最后一个元素。

最后析构掉原来的空间。

2)有空间,顺序插入即可。

STL-05-vector使用及其源码剖析_第12张图片
接下来验证一下,扩增时会调用拷贝构造函数。

STL-05-vector使用及其源码剖析_第13张图片
从结果可以看到,确实扩容的时候要将所有的元素全部搬运进新的空间。

通过对比还是觉得G2.9版本的可读性比较好

你可能感兴趣的:(STL)