STL中的deque及源码实现 std::deque

本博客中涉及到的所有代码均在我的github上存放,地址:mySTL

如果有兴趣的话可以去下载查看,注释比较详尽。

说点什么

相信大家如果对C++有一定的了解的话,都会知道C++中有STL这个超大的模版库,这个模版库提供了非常多的模版容器和模版算法,如常用的vectorliststackqueuemapset等等容器,sortfind_iffindswap等模版函数
这个库由于创建时间过长、版本更替过多,现在也越来越臃肿了,导致我们想要去探究其源码的难度也越来越高(比如很多的编译时的宏和各种千奇百怪的性能提升手段),但是千变万变,这些牺牲代码可读性的措施都是为了提高算法和容器的效率或者说空间利用率
不过其实质的原理还是差不多的,比如各种空间构造和内存存储方式大致上都是差不多的,但具体到很细节的东西,各个版本就有各个版本的不同

比如这次我们要介绍的deque,就是我根据比较易懂的版本自行写出的代码,所以注释还是比较充足的。
首先还是惯例,先介绍一下deque

deque的基本介绍

std::dequedouble-ended queue ,双端队列)是可以进行下标访问的顺序容器,它允许在其首尾两端快速插入及删除元素。
另外,在 deque 任一端插入或删除元素不会让当前正在使用的迭代器失效,至于原因,这个就和deque的实现方式有很大的关系了。

std::vector 相反, deque 的元素不一定是相邻存储的:典型实现是采用单独分配的固定大小的相邻元素数组,外加一个额外的数组去存储这些空间的首地址,这表示下标访问必须进行二次指针解引用,与之相比 vector 的下标访问只需要进行一次。

deque 的存储按需自动扩展及收缩。扩张 deque 比扩展 std::vector 的消耗要少,因为它不涉及到复制当前的元素到新内存位置。但是同时, deque 也因此拥有较大的最小内存开销。就算只保有一个元素的 deque 也必须为其分配至少一个内存数组(例如 64 位 libstdc++ 上为对象大小的 8 倍空间; 64 位 libc++ 上为对象大小的16 倍或 4096 字节的较大者)。

deque 上常见操作的复杂度(效率)如下:

  • 随机访问——常数 O(1)
  • 在结尾或起始插入或移除元素——常数 O(1)
  • 插入或移除元素——线性 O(n)

deque的内存布局

其主要的内存布局大致如图:
这里写图片描述

通过上面的空间构造,我们可以知道,我们在使用deque的的元素操作的时候(比如[ ]操作,或者迭代器的++操作的时候,并不是简单的将其指针+1或者+n ),所以我们需要进行更加细致的设计和安排,为deque设计一个特化的、合适的迭代器,以及设计和其对应的空间配置方案

deque需要维护一个指向各个连续内存空间的指针数组,所以它的迭代器势必也要能够判断各个连续空间的边界以便于知道自己该如何进行++- -,下面将会对这个迭代器进行一定的代码分析。
deque最重要的就是其空间不足进行重新配置的过程,了解了这个,我们差不多就完全理解了deque是个怎样的东西
我们边看代码边说吧,毕竟网上关于deque的内存布局的东西已经说的太多了

以下代码仅供参考,不具备实际操作的意义。

deque的类定义

template<
    class T,
    class Allocator = std::allocator<T>

> class deque;

以上就是一个典型的deque的头部

T 必须满足可复制赋值 (CopyAssignable) 和可复制构造 (CopyConstructible) 的要求。

Allocator 用于获取/释放内存及构造/析构内存中元素的分配器。类型必须满足分配器 (Allocator) 的要求。若 Allocator::value_typeT 不同则行为未定义。

以下是我自己写的deque的头文件代码(说是头文件,实质上模版类只含有头文件,其定义我写在了另外一个头文件中#include"Deque_detail.h"),其完整头文件代码如下:

#ifndef _DEQUE_H_
#define _DEQUE_H_
#include"Allocator.h"
#include"Iterator.h"
#include"Algorithm.h"
#include"UninitializedFunc.h"
namespace STL {
	template<class T, class Alloc = allocator<T>>
	class deque;
	//deque_iterator detail
	namespace Detail {

		template<class T>
		class deque_iterator :public iterator<random_access_i
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值