SGISTL源码探究-deque容器(上)

前言

deque容器比list以及vector容器都要复杂的多。它用两端都有开口的线性空间来存储数据,这样的话在首部操作数据的效率比vector高,以及虽然它的迭代器是random_access_iterator_tag型的,但是并不是原生指针,需要封装,比listvector的迭代器都要复杂。它实现的机制是利用二级指针,维护一个指针数组map,然后数组中存储的指针指向具体的线性空间。
map并不是从开头依次使用,而是先选择二级指针数组中间的部分使用,这是为了deque能够前后都加入等量的元素。我们把二级指针数组称为deque的中控器,通过中控器得到真正存储元素的空间。

deque的中控器

首先我们先简单介绍一下map相关的知识,即定义部分,这样有利于我们后面对迭代器等知识的分析。
这里先列出部分源码:

//可以看到多了一个缺省参数BufSiz=0
//具体有什么作用,我们看到后面再说
template <class T, class Alloc = alloc, size_t BufSiz = 0>
class deque {
public:                         // Basic types
  //一些常用类型的声明
  typedef T value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef value_type& reference;
  typedef const value_type& const_reference;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;

public:                         // Iterators
  //迭代器的声明
#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
  typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;
  typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;
#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
  typedef __deque_iterator<T, T&, T*>                      iterator;
  typedef __deque_iterator<T, const T&, const T*>          const_iterator;
#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
...
protected:                      // Internal typedefs
  /* map_pointer的类型即T **
   * 它先指向指针数组,指针数组里面的指针再指向存储元素的线性空间(即结点)
   */
  typedef pointer* map_pointer;
  /* 这里需要注意一下
   * deque容器有两个空间配置器
   * 一个用于配置元素
   * 另一个用于配置指针数组
   */
  typedef simple_alloc<value_type, Alloc> data_allocator;
  typedef simple_alloc<pointer, Alloc> map_allocator;

使用这样的设计需要注意到几个问题。虽然每一个指针指向的空间是连续的,但是当一段数据横跨多个指针指向的连续空间时,就需要指针的切换了。如果要维持这种连续空间的假象,则需要考虑到每个线性空间跳到下一个线性空间的边界情况。
以及当指针数组不够大时需要再继续分配的情况。
为了支持这些操作,deque的迭代器确实要复杂一些。下面我们就来看看deque的迭代器源码。

deque的迭代器

大概有100多行的样子,deque的迭代器除了要取元素的值这些操作以外,还需要知道指针指向的一段线性空间的首尾,不然++或者--操作的时候,无法跳转到另外一段线性空间。

template <class T, class Ref, class Ptr, size_t BufSiz>
struct __deque_iterator {
  //声明迭代器
  typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;
  typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
  static size_t buffer_size() {
  return __deque_buf_size(BufSiz, sizeof(T)); }
#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
template <class T, class Ref, class Ptr>
struct __deque_iterator {
  typedef __deque_iterator<T, T&, T*>             iterator;
  typedef __deque_iterator<T, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值