STL之vector

一、vector与array的区别:

 array是静态空间,一旦配置了就不能改变,如果要换个大一点的房子,首先:需要配置一块新空间,然后将元素从旧地址一一搬到新地址,再把原来的空间释放给系统;vector是动态空间,随着元素的加入,它的内部机制就会自行扩充空间以容纳新元素。vector是吃多少用多少;

vector实现技术的关键在于:其对大小的控制以及重新配置时的数据移动效率。

二、vector的迭代器:

vector 维护的是一个连续线性空间,所以不论其元素型别为何,普通指标都可以做为 vector 的迭代器而满足所有必要条件,因为 vector 迭代器所需要的操作行为如operator*,operator->,operator++,operator--,operator+, operator-,operator+=,operator-=,普通指标*天生就具备。vector 支援随机存取,而原
生指标正有着这样的能力。所以,vector 提供的是 Random Access Iterators

 1  1 template<typename T,typename Alloc=alloc>
 2  2  class vector
 3  3  {
 4  4  public:
 5  5  typedef    T                    value_type;
 6  6  typedef   value_type*          pointer;
 7  7  typedef   ptrdiff_t             difference_type;
 8  8  typedef   value_type*           iterator; //vector的迭代器是普通指针
 9  9  typedef   value_type&           reference;
10 10  typedef   size_t                size_type;
11 11  protected12 12  typedef simple_alloc<value_type,Alloc> data_alllocator;
13 13 // .....                           其他的后面再说    
14 14 };
15 15 
16 16 vector<int>::iterator ivite;   //ivite的性别是int*
17 17 vector<Shape>::iterator svite; //svite的型别是Shape*

三、vector的数据结构:

vector 所采用的数据结构非常简单:线性连续空间。它以两个迭代器 start finish 分别指向配置得来的连 续 空 间 中 目 前 已 被 使 用 的 范 围 , 并 以 迭 代 器end_of_storage 指向整块连续空间(含备用空间)的尾端:

1 template <class T, class Alloc = alloc>
2 class vector {
3 ...
4 protected:
5     iterator start;// 表示目前使用空间的头
6     iterator finish;// 表示目前使用空间的尾
7     iterator end_of_storage; // 表示目前可用空间的尾
8 ...
9 };

为了降低vector的配置成本,vector实际配置的大小可能比需求大一些,这就是vector的容量(capacity),一个vector的容量永远大于等于大小,一旦容量等于大小,那么vector就需要另觅它所。

 运用 start, finish, end_of_storage 三个迭代器,便可轻易提供首尾标示、大小、容量、空容器判断、注标([ ])运算子、最前端元素值、最后端元素值…等机能:

 1 template <class T, class Alloc = alloc>
 2 class vector {
 3     ...
 4 public:
 5     iterator begin() { return start; }
 6     iterator end() { return finish; }
 7     size_type size() const { return size_type(end() - begin()); }
 8     size_type capacity() const {
 9         return size_type(end_of_storage - begin());
10     }
11     bool empty() const { return begin() == end(); }
12     reference operator[](size_type n) { return *(begin() + n); }
13     reference front() { return *begin(); }
14     reference back() { return *(end() - 1); }
15     ...
16 };

四、vector的构造与内存管理:

1、空间配置

vector缺省使用alloc作为空间配置器,并据此另外定义了一个data_allocator,为的是更方便以元素大小为配置单位:

1 template <class T, class Alloc = alloc>
2 class vector {
3 protected:
4     // simple_alloc<>
5     typedef simple_alloc<value_type, Alloc> data_allocator;
6     ...
7 };
8 data_allocator::allocatore(n) //表示配置n个内存空间

2、构造函数

vector提供许多constructors,其中一个允许我们指定空间大小及初值:

 1 // 构造函数,允许指定 vector 大小 n 和初值 value
 2 vector(size_type n, const T& value) { fill_initialize(n, value); }
 3 // 充填并予以初始化
 4 void fill_initialize(size_type n, const T& value) {
 5     start = allocate_and_fill(n, value);
 6     finish = start + n;
 7     end_of_storage = finish; //指向整块连续备用空间的尾端
 8 }
 9 // 配置而后填充
10 iterator allocate_and_fill(size_type n, const T& x) {
11     iterator result = data_allocator::allocate(n); // 配置n 个元素空间
12     uninitialized_fill_n(result, n, x); // 全局函数
13     return result;
14 }

3.插入元素

当我们以push_back()将新元素插入vector尾端时,该函数首先检查是否还有备用空间,如果还有备用空间,就直接在备用空间上构造元素,并调整迭代器的finish,使得vector变大,如果没有空间了,就直接扩充空间(重新配置、移动数据、释放原空间)

参考文献

https://blog.csdn.net/itismelzp/article/details/50241105

 
陈小洁的三只猫
原文地址:https://www.cnblogs.com/ccpang/p/11303911.html