序列式容器(Vector)
前言
在STL编程中,我们最常用到的就是容器,容器可分为序列容器和关联容器;本文记录的是我们经常使用的序列容器之vector,vector的数据安排和操作方式类似于C++内置数组类型array,唯一的区别就是在于空间的灵活运用。内置数组array是静态空间,一旦分配了内存空间就不能改变,而vector容器可以根据用户数据的变化而不断调整内存空间的大小。
vector容器有已使用空间和可用空间,已使用空间是指vector容器的大小,可用空间是指vector容器可容纳的最大数据空间capacity。vector容器是占用一段连续线性空间,所以vector容器的迭代器就等价于原生态的指针;
vector的实现依赖于内存的配置和内存的初始化,以及迭代器。其中内存的配置是最重要的,因为每当配置内存空间时,可能会发生数据移动,回收旧的内存空间,如果不断地重复这些操作会降低操作效率,所有vector容器在分配内存时,并不是用户数据占多少就分配多少,它会分配一些内存空间留着备用,即是用户可用空间。关于vector类定义可参考《vector库文件》或者《MSDN库的vector类》。
vector容器的数据结构
vector容器采用的是线性连续空间的数据结构,使用两个迭代器来管理这片连续内存空间,这两个迭代器分别是指向目前使用空间的头start和指向目前使用空间的尾finish,两个迭代器的范围[start,finish)表示容器的大小size()。由于为了提高容器的访问效率,为用户分配内存空间时,会分配多余的备用空间,即容器的容量,以迭代器end_of_storage作为可用空间的尾,则容器的容量capacity()为[start,end_of_storage)范围的线性连续空间。
//Alloc是SGI STL的空间配置器,默认是第二级配置器
15 namespace EasySTL
16 {
17 /******** vector ***********/
18 template<class T, class Alloc = alloc>
19 class vector
{
30 protected:
31 //simple_alloc 是空间配置器
32 typedef simple_alloc<value_type, Alloc> data_allocator;
33
34 iterator start_; //目前使用空间头
35 iterator finish_;//目前使用空间尾
36 iterator end_of_storage_;//目前可用空间的尾
...
}
}
下面给出vector的数据结构示意图:
vector迭代器
vector容器维护的空间的线性连续的,所以普通指针也可以作为迭代器,满足vector的访问操作;如:operator*,operator->,operator++,operator–,operator+,operator-,operator+=,operator-=等操作;同时vector容器支持随机访问,所以,vector提供的是随机访问迭代器。
15 namespace EasySTL
16 {
17 /******** vector ***********/
18 template<class T, class Alloc = alloc>
19 class vector
{
20 public:
21 //vector的嵌套型别定义,是iterator_traits<T>服务的类型
22 typedef T value_type;
23 typedef T* pointer;
24 typedef T* iterator;
25 typedef const T* const_pointer;
26 typedef T& reference;
27 typedef size_t size_type;
28 typedef ptrdiff_t difference_type;
56 public: //以下定义vector迭代器
57 iterator begin() const { return start_; }
58 iterator end() const { return finish_; }
59 size_type size() const { return size_type(end() - begin()); }
60 size_type capacity() const { return size_type(end_of_storage_ - begin()); }
61 bool empty() const { return begin() == end(); }
...
}
}
vector的构造函数和析构函数
这里把vector容器的构造函数列出来讲解,主要是我们平常使用vector容器时,首先要要定义相应的容器对象&