由于vector容器需要确保数据是在内存中连续存储,所以一般需要预先申请一片连续的空间来顺序的存储数据,当这块空间填满之后就需要申请一块更大的空间,然后把原来的数据重新拷贝到新的空间上以确保数据存储的连续性.
我们的内存预分配策略就是,对于空的vector起始预分配1个数据大小,然后不够的时候翻倍,即2,4,8,….之所以这样分配是为了和前面说的Allocator对应起来,因为freelist指向的都是2的指数次的空间. 另外,如果初始化vector容器时候就有一定个数的数据,比如有k个,那么预留的数据个数就是最小的那个大于等于k且是2的整数次幂的数.
从上面的内存策略可以看到我们需要维持三个指针,一个指针指向目前申请空间的起始地址,一个指向结束地址,一个指向可用的剩余空间的地址.至于空间的申请,则完全交给前面说到的Allocator来处理.
vector容器也需要一个迭代器以支持很多基于迭代器的算法或者成员函数,一般来说容器的迭代器都是很容器的存储方式有关,由于vector的数据是类似数组一样的顺序存储,所以可以直接用指针来作为迭代器,不必单独定义一个迭代器类.
一个为当前vector assign n个value,一个是将[begin, end)里的数据assign给当前vector,它们两个似乎没有什么冲突,但是会有什么问题呢?
我们可以看到第一个assign函数的第一个参数是size_type即unsigned int,第二个参数是const T; 我们可以想一下,如果这个T是int,那么我们如果使用assgin(3, 3)本意调用第一个assgin函数,那么就是形参都是int,所以会将InputIterator解释为int,然后匹配第二个assgin函数!!!除非我们assgin((unsigned int)3, 3)这样调用才会匹配到第一个assgin函数,这当然是不方便的.所以我们需要针对这种情况判断InputIterator是否是int类型,如果是则再调用第一个assgin函数. 同理,我们可以看到vector的迭代器构造函数,以及insert函数都有这样的问题,也需要这样解决.