本篇文章基于gcc中stl的源码介绍deque容器的整体实现和它的内存结构。
说明一下,我用的是gcc7.1.0编译器,标准库源代码也是这个版本的。
首先呢,还是看一下思维导图,如下:
1. deque容器整体源码实现介绍
deque容器是stl中顺序容器的一种,之前已经介绍过array和vector了,今天介绍deque容器,deque的本质是一个类模板,它的声明位于头文件bits/stl_deque.h
,实现位于bits/deque.tcc
,接下来我们就围绕这两个文件来介绍一下deque容器的实现原理。
先看一下deque容器相关的一个整体类图:
下面对这个类图进行一个简单的解读:
- deque容器保护继承于类模板
_Deque_base
,也就是_Deque_base
是deque的基类,并且内存分配和释放都是通过基类来完成的; - 容器首地址和迭代器等保存在结构体成员变量
_M_impl
中,它继承于别名类型_Tp_alloc_type
,最终的内存分配其实就是通过它完成的; - deque容器使用了它自己的迭代器
_Deque_iterator
,没有直接使用stl中的公共迭代器,且迭代器里面保存了当前地址、首地址、尾地址以及当前节点。
这里有几个类型是不好理解的,第一个是_Tp_alloc_type
,这是一个别名,关于这个类型的解读,我之前专门写过一篇文章:三张图带你弄懂STL中内存分配器
然后就是_Elt_pointer
和_Map_pointer
这两个类型,他们的原型如下:
//这里_Tp是模板类型
#if __cplusplus < 201103L
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
typedef _Tp* _Elt_pointer;
typedef _Tp** _Map_pointer;
#else
private:
template<typename _Up>
using __ptr_to = typename pointer_traits<_Ptr>::template rebind<_Up>;
template<typename _CvTp>
using __iter = _Deque_iterator<_Tp, _CvTp&, __ptr_to<_CvTp>>;
public: