c++stl vector源码简析
vector是我们经常用的容易之一,我们现在来简单看一下vector的部分源码理解vector的行为以便我们在使用过程中更得心应手
首先看一下vector的alloc基类:
template <class _Tp, class _Allocator, bool _IsStatic>
class _Vector_alloc_base {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_data_allocator; }
_Vector_alloc_base(const allocator_type& __a)
: _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
allocator_type _M_data_allocator;
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator.allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ if (__p) _M_data_allocator.deallocate(__p, __n); }
};
可以看到成员变量部分有start,finish ,end
首先说明一点vector是一个长度可变的容器,为了保证它在末尾插入的效率 它实际的存储空间是大于它的size的
size大小为start到finish,实际容量是start到end;
成员变量还有一个分配器,源码中有这样的注释
// Base class for ordinary allocators.
这是一个普通的分配器
源码中还定义了另一个类
// Specialization for allocators that have the property that we don't
// actually have to store an allocator object.
在这个类里面是通过调用函数返回一个分配器对象 目前他们两个的区别和作用我还不了解 等以后了解过后再来补充
接下来是vector的基类
template <class _Tp, class _Alloc>
class _Vector_base {
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_base(const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
_Vector_base(size_t __n, const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _M_data_allocator::deallocate(__p, __n); }
};
可以看见有两种构造函数一种传入了分配空间的大小,一种没有传入大小
传入大小的构造函数和析构函数分别调用了下面的分配内存的函数和清空内存的函数
接下来就是vector类的,因为vecotor类代码较长我就拆解下来看
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef