SGI STL容器vector源码解析

vector是个序列容器,被称为动态数组,类似于C/C++中的数组,但是其空间能够动态变化。
使用只需要包含vector/vector.h头文件,但是SGI将其实现在stl_vector.h头文件。
实现如下:

首先定义了vector基类_Vector_base,主要用于两个目的,首先,_Vector_base的构造器和析构器只分配空间单不初始化,这使得异常安全更容易;其次,封装了SGI风格的配置器和STL标准风格配置器间的差异(通过条件编译实现)。

#ifdef __STL_USE_STD_ALLOCATORS
//STL标准风格
// Base class for ordinary allocators.
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) //分配空间
    {  _M_data_allocator.allocate(__n); } 
  void _M_deallocate(_Tp* __p, size_t __n) //释放空间
    { if (__p) _M_data_allocator.deallocate(__p, __n); }
};

// Specialization for allocators that have the property that we don't
// actually have to store an allocator object.  
template <class _Tp, class _Allocator> //偏特化版本,不必要定义空间配置器成员变量
class _Vector_alloc_base<_Tp, _Allocator, true> {
public:
  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
          allocator_type;
  allocator_type get_allocator() const { return allocator_type(); }

  _Vector_alloc_base(const allocator_type&)
    : _M_start(0), _M_finish(0), _M_end_of_storage(0) 
  {}

protected:
  _Tp* _M_start;
  _Tp* _M_finish;
  _Tp* _M_end_of_storage;

  typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
  _Tp* _M_allocate(size_t __n)
    { return _Alloc_type::allocate(__n); }
  void _M_deallocate(_Tp* __p, size_t __n)
    { _Alloc_type::deallocate(__p, __n);}
};

template <class _Tp, class _Alloc>
struct _Vector_base //vector基类
  : public _Vector_alloc_base<_Tp, _Alloc,
                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{
  typedef _Vector_alloc_base<_Tp, _Alloc, 
                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
          _Base;
  typedef typename _Base::allocator_type allocator_type;

  _Vector_base(const allocator_type& __a) : _Base(__a) {}
  _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
    _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); }
};    

#else /* __STL_USE_STD_ALLOCATORS */
//SGI风格
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; //SGI风格空间配置器
  _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); }
};

#endif /* __STL_USE_STD_ALLOCATORS */

这里写图片描述
vector容器中元素分配的是线性空间,通过三个指针
_Tp* _M_start; //指向目前使用空间的头
_Tp* _M_finish; //指向目前使用空间的尾
_Tp* _M_end_of_storage; //指向目前可用空间的尾
管理这个线性空间。

vector实现继承至vector基类_Vector_base

template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > 
class vector : protected _Vector_base<_Tp, _Alloc> 
{
    ...
}

模板参数_Tp指的是vector容器中元素类型,_Alloc指的是vector中采用的空间配置器,默认的是SGI中自己实现的。

内嵌型别定义

  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 const value_type& const_reference; //常量引用型别定义
  typedef size_t size_type; 
  typedef ptrdiff_t difference_type;

  typedef typename _Base::allocator_type allocator_type; //空间配置器型别定义,加typename告诉编译器这是模板
  allocator_type get_allocator() const { return _Base::get_allocator(); } //返回空间配置 器类型

#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  typedef reverse_iterator<const_iterator> const_reverse_iterator;
  typedef reverse_iterator<iterator> reverse_iterator; //反向迭代器型别定义
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  typedef reverse_iterator<const_iterator, value_type, const_reference, 
                           difference_type>  const_reverse_iterator;
  typedef reverse_iterator<iterator, value_type, reference, difference_type>
          reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */

构造器

  • 默认构造器
explicit vector(const allocator_type& __a = allocator_type()) 
    : _Base(__a) {}

定义为显示,禁止隐式转换。

  • 填充构造器
vector(size_type __n, const _Tp& __value,
         const allocator_type& __a = allocator_type()) 
    : _Base(__n, __a)
    { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }

explicit vector(size_type __n)
    : _Base(__n, allocator_type())
    { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }

调用了uninitialized_fill_n全局函数。

  • 范围构造器
#ifdef __STL_MEMBER_TEMPLATES 
  // Check whether it's an integral type.  If so, it's not an iterator.
  template <class _InputIterator>
  vector(_InputIterator __first, _InputIterator __last,
         const allocator_type& __a = allocator_type()) : _Base(__a) {
    typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
    _M_initialize_aux(__first, __last, _Integral());
  }

  
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值