【STL源码剖析】总结笔记(7):巧妙的deque

00 写在前面

【STL源码剖析】总结笔记(6):iterator的设计与神奇的traits

在掌握了迭代器的基本设计原理之后,我们就可以来看剩下的序列式容器的实现了。这时我们可以把注意力更多地集中在每一个容器本身的设计上。

01 概述

deque是一种双向开口的连续线性空间,也就是可以在头尾两端进行插入和删除操作。我们知道vector是单向开口的连续线性空间,在空间不足的时候需要另寻更大的空间并进行移植。

为什么说deque巧妙呢,因为deque没有容量的概念,可以动态地增加空间。

但是这种连续其实只是deque营造的一种“假象”,我们先来看一下deque是如何实现连续的。

image-20211029110855452

先不去看iterator,只看中间部分。

可以发现map的地方控制着很多的指针,而每个指针都指向一块buffer。

在添加元素时,只需要在buffer中添加即可。如果到达边界,那么就再扩充map中维护的指针即可。这也就是为什么deque可以左右扩充的原因。

但这也意味着想要维持连续的“假象”,iterator将会做出巨大的改变(重载)来实现比如++,–的操作。

后面我们来一一说明。

02 deque的结构

从上图中我们简单的了解了一下deque的结构。

这里的map其实就是deque的控制中心(注意这个map不是STL中的map)。map是一小块连续的空间(底层其实就是vector),其中的每一个node指向一大段连续空间buffer,在STL中可以指定其大小。

直接来看实现:

template <class T,class Alloc=alloc,size_t BufSize=0>
class deque{
    public:
    	typedef T value_type;
    	typedef _deque_iterator<T,T&,T*,BufSiz>iterator;
    protected:
    	typedef pointer* map_pointer;
    protected:
    	iterator start;
    	iterator finish;
    	map_pointer map;//1
    	size_type map_size;//2
}

对照上图来看这段代码

  1. 首先关注map,map是指向控制中心这段空间的指针,而这其中又包含着指针,所以map的类型是指针的指针。(T**)

  2. map_size就是map的大小,比如上图中就是8。

  3. 我们可以思考一下deque的大小是多少字节。

    map是指针结构:4字节。map_size 4字节。还需要知道iterator的大小。

    而在iterator里有上图中的表示的四个部分:cur,first,last,node。一共是16字节。

    所以deque的大小是16+16+4+4=40字节

03 deque的迭代器

接下来我们可以仔细研究一下deque的迭代器了,这也是deque的灵魂。因为deque内部本身缓冲区的分割开的,如果想要使其连续,iterator必须可以精确地找到上一个或者下一个buffer的位置,要做一些特殊情况的判断。

iterator的结

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值