STL容器源码剖析 (vector)
STL在日程编程应用非常的广泛,之前看到一篇大牛文章说,用C++开发,尽量用容器类+迭代器来代替数组+指针,因为数组+指针容易越界,或者内存泄露,相反,容器类和+迭代器都有大神将底层封装好,使用安全简单。
vector是有序容器里使用最广泛的容器,基本能够支持任何类型的对象,同时也是一个可以动态增长的数组。vector容器有已使用空间和可用空间,已使用空间是指vector容器的大小,可用空间是指vector容器可容纳的最大数据空间capacity。vector的实现依赖于内存的配置和内存的初始化,以及迭代器。其中内存的配置是最重要的,因为每当配置内存空间时,可能会发生数据移动,回收旧的内存空间,如果不断地重复这些操作会降低操作效率,所有vector容器在分配内存时,并不是用户数据占多少就分配多少,它会分配一些内存空间留着备用,即是用户可用空间。关于vector类定义可参考vector,以下源代码在SGI STL的文件<stl_vector.h>中。
vector容器的数据结构
vector使用两个迭代器来管理连续内存空间,分别是指向目前使用空间的头start和指向目前使用空间的尾finish。还有以迭代器end_of_storage作为可用空间的尾。具体如下,
//Alloc是SGI STL的空间配置器,默认是第二级配置器
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector : protected _Vector_base<_Tp, _Alloc>
{
...
protected:
_Tp* _M_start;//表示目前使用空间的头
_Tp* _M_finish;//表示目前使用空间的尾
_Tp* _M_end_of_storage;//表示目前可用空间的尾
...
};
vector迭代器
vector容器维护的空间的线性连续的,所以普通指针也可以作为迭代器。如:operator*,operator->,operator++,operator–,operator+,operator-,operator+=,operator-=等操作。
//Alloc是SGI STL的空间配置器,默认是第二级配置器
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector : protected _Vector_base<_Tp, _Alloc>
{
public://vector的内嵌型别定义,是iterator_traits<I>服务的类型
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;//vector容器的迭代器是普通指针
typedef const value_type* const_iterator;
...
public://以下定义vector迭代器
iterator begin() { return _M_start; }//指向已使用空间头的迭代器
const_iterator begin() const { return _M_start; }
iterator end() { return _M_finish; }//指向已使用空间尾的迭代器
const_iterator end() const { return _M_finish; }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
...
};
vector的构造函数和析构函数
我们平时定义vector对象是会用到,如 vector vec,vector str(n)等等
/*以下是vector容器的构造函数***********************
/************************************
*** //默认构造函数***************************
* explicit vector( const Allocator& alloc = Allocator() ); *
*** //具有初始值和容器大小的构造函数*******************
* explicit vector( size_type count, *
* const T& value = T(), *
* const Allocator& alloc = Allocator()); *
* vector( size_type count, *
* const T& value,