前文
vector是stl库中非常重要的一个容器,熟练使用vector可以有效提高我们的代码效率以及逼格,而模拟实现vector能使我们深入了解vector一些重要机制以及使用方法。
本文将带领铁子们完成 vector一些重要接口的实现
老规矩, 源码结尾自取。
一,vector的成员变量

首先我们可以先观察在stl30的源码中,vector的成员变量与之前的string大有不同。
由上图可以看到 三个成员变量全都是指针。
那么这些指针都代表什么意思,指向哪里呢?
start指向 空间开始的位置, finish指向 空间中最后一个有效数据的下一个位置, end_of_storage指向的是 空间最大容量的下一个位置。

而我们的模拟实现vectord的成员变量自然也要向源码看齐。
当然我们后续的功能肯定是不能照搬源码的,源码只是一个参考,而我们模拟实现的目的也是更加深入的了解vector,只要实现的功能和源码的功能相同或者类似就好。
成员变量如下:
typedef V* iterator;
typedef const V* const_iterator;
iterator _start;//指向空间最开始的地址
iterator _finsh;//指向空间有效数据的下一个地址
iterator _end_of_storage;//指向空间最大容量的下一个地址
二,构造函数/析构函数
2.1 构造函数

如图,构造函数共有四种,我们要实现的是前三种。
2.1.1 无参构造函数
对于无参构造函数,我们只要将成员变量进行初始化即可。
//1.无参
vector()
:_start(nullptr)
,_finsh(nullptr)
,_end_of_storage(nullptr)
{}
2.1.2 有参构造函数
有参构造函数,我们需要先 开辟n个大小的空间,再将数据 一个一个尾插进去即可。
ps: 扩容和尾插函数后续马上就会讲到,铁子们也可以先看扩容和尾插函数,再回头看这个。
//2.有参数
vector(size_t n, const V& val = V())
:_start(nullptr)
, _finsh(nullptr)
, _end_of_storage(nullptr)
{
reserve(n);
for (size_t i = 0; i < n; i++)
{
push_back(val);
}
}
//int函数重载,原因马上讲到
vector(int n, const V& val = V())
:_start(nullptr)
, _finsh(nullptr)
, _end_of_storage(nullptr)
{
reserve(n);
for (int i = 0; i < n; i++)
{
push_back(val);
}
}
2.1.3 范围构造函数
范围构造函数,故名思义就是构造一个范围为[first,last)的vector,然后vector中的每个数据都和范围中的数据一一对应。
实现逻辑:先 开辟和范围一样大小的空间 , 再将数据一一尾插即可 。
代码如下:
//3,范围构造
template <class InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr)
, _finsh(nullptr)
, _end_of_storage(nullptr)
{
size_t n = last - first;
reserve(n);
while (first != last)
{
push_back(*first);
first++;
}
}
2.1.4 函数构造适配的问题
相信老铁们已经看到有参构造函数的代码中有一个int类型的重载,那么这是为什么呢?
我们可以先将int重载代码屏蔽,然后实验一下
