deque
deque文档
deque,她的意思为双端队列(double-ended queue)。逻辑上看,deque和vector都是连续空间。相比于vector只能从尾部增长元素,而deque可在双侧增加元素。但是从存储结构上,deque并非是连续空间存储的。它是分段连续的。对于vector存储(申请的内存)的增长,可以描述为三个步骤1.申请内存2.搬移元素3释放原先的使用的内存。而由于deque其特殊的数据结构,如下图所示,省去这三个步骤。(但是仍然需要申请buffer去存储新元素,不用去搬移旧有元素了)。
deque的组成(数据成员):
iterator start; iterator finish; map_pointer map; size_type mapsize;//map大小
由于其特殊的数据结构,其迭代器的设计也会较为繁琐。因为是分段连续的。尤其是跨过分段是的特殊处理需要尤其注意。对于下图的说明:map存储着各个buffer(存储数据的数据段)的指针。迭代器(start,finish)则存储着该元素所在buffer的首尾,以及,目前所在位置(cur),还有其所在buffer在map上的信息。因此迭代器的设计较与vector的设计还是非常复杂的。

deque的构造与析构
构造函数:与vector,string之前的构造函数类似
| 构造函数类型 | 具体函数 |
|---|---|
| default (1) | deque(); explicit deque (const allocator_type& alloc); |
| fill (2) | explicit deque (size_type n, const allocator_type& alloc = allocator_type()); deque (size_type n, const value_type& val, const allocator_type& alloc = allocator_type()); |
| range (3) | template < class InputIterato r> deque (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
| copy (4) | deque (const deque& x); deque (const deque& x, const allocator_type& alloc); |
| move (5) | deque (deque&& x); deque (deque&& x, const allocator_type& alloc); |
| initializerlist(6) | deque (initializer_list il, const allocator_type& alloc = allocator_type()); |
= 赋值
| 赋值函数类型 | 等号重载 |
|---|---|
| copy (1) | deque& operator= (const deque& x); //拷贝赋值函数 |
| move (2) | deque& operator= (deque&& x); //移动赋值函数 |
| initializer list (3) | deque& operator= (initializer_list il);//利用初始化列表进行赋值 |
assign
| 赋值函数类型 | 重载 |
|---|---|
| range (1) | template void assign (InputIterator first, InputIterator last); |
| fill (2) | void assign (size_type n, const value_type& val) ; |
| initializer list (3) | void assign (initializer_list il); |
deque元素访问
迭代器(类指针访问方式)
值得注意的是:虽然deque的内存表现不是连续的(分段连续),但是通过存储的数据,通过对一些符号的重载,仍能使得我们像连续空间那样去使用迭代器。迭代器只不过是定义了一堆行为像指针的类而已。对于下面的各个函数,其中以“c"开头的函数(如cbegin()、cend()),返回的是const iterator类型(类似于指向常量的指针),而"r"与”cr“开头表示(const and reverse),反向迭代器以及常量反向迭代器。
| Iterators | |
|---|---|
| begin cbegin | returns an iterator to the beginning (public member function) |
| end cend | returns an iterator to the end (public member function) |
| rbegin crbegin | returns a reverse iterator to the beginning (public member function) |
| rend crend | returns a reverse iterator to the end (public member function) |
元素访问
| Element access | 函数原型及其说明 |
|---|---|
| at | access specified element with bounds checking (public member function),带有边界检查的访问特定元素访问方式 reference at( size_type pos ); const_reference at( size_type pos ) const; |
| operator[] | access specified element (public member function) reference operator[ ] ( size_type pos ); const_reference operator[ ] ( size_type pos ) const; |
| front | access the first element (public member function) reference front(); const_reference front() const; |
| back | access the last element (public member function) reference back(); const_reference back() const; |
容量与大小
不同与vector,string有capacity函数可以查看已经申请的空间。而deque不行。实际通过了解其的数据成员可以知道,不像vector有end_of_storage这样的迭代器,并且也可以知道他也
| Capacity | 函数原型及说明 |
|---|---|
| empty | checks whether the container is empty (public member function),判断容器是否为空 bool empty() const; |
| size | returns the number of elements (public member function) size_type size() const; |
| max_size | returns the maximum possible number of elements (public member function),返回可能的最大元素个数 size_type max_size() const; |
| shrink_to_fit(C++11) | reduces memory usage by freeing unused memory (public member function),可以释放内存 void shrink_to_fit(); |
容器修改
对于clear函数。对于vector不会释放其内存空间。而clear会。(这点可以通过申请一个比较大的内存的deque,然后观察程序的占用内存变化,可以清楚看到deque的clear是会释放内存的)。对于使用clear后的所占有的内存大小。可以参考,《STL源码分析》中的一段话:deque的最初状态(无任何元素时)保有一个缓冲区,因此,clear()完成之后回复初始状态,也一样要保留一个缓冲区。
对于emplace,这个函数是想要通过传入的参数以及所申请的空间,直接在指定位置构造新元素。由于内存结构仍然是线性的,所以在中间部分emplace的效率仍然是很低的,不如list以及foward_list。
对于swap。在vector有这样的小技巧(可以使一个vector对象与一个右值swap,可以达到释放空间的目的)
vector<int> v1{1,2,3};
v1.swap((vector<int>){1});//对于vector可行,对于deque不可行,因为没有传入右值参数的函数原型
| Modifiers | 函数原型及说明 |
|---|---|
| clear | clears the contents (public member function),清除内容,所有迭代器失效。deque的clear会清除部分申请的内存空间! void clear(); |
| insert | inserts elements (public member function)依据传入参数分类 single element (1) 单元素 iterator insert (iterator position, const value_type& val); fill (2) 填充 void insert (iterator position, size_type n, const value_type& val); range (3) 通过迭代器的范围插入(要求值类型一致) template < class InputIterator > void insert (iterator position, InputIterator first, InputIterator last); |
| emplace(C++11) | constructs element in-place (public member function)在指定位置构造元素 template <class... Args> iterator emplace (const_iterator position, Args&&... args); |
| erase | erases elements (public member function) iterator erase (const_iterator position ); iterator erase (const_iterator first, const_iterator last ); |
| push_back | adds an element to the end (public member function) void push_back (const value_type& val); void push_back (value_type&& val); |
| emplace_backC++11) | constructs an element in-place at the end (public member function) template <class... Args> void emplace_back (Args&&... args); |
| pop_back | removes the last element (public member function) void pop_front(); |
| push_front | inserts an element to the beginning (public member function) void push_front (const value_type& val); void push_front (value_type&& val); |
| emplace_frontC++11) | constructs an element in-place at the beginning (public member function) template <class... Args> void emplace_front (Args&&... args); |
| pop_front | removes the first element (public member function) void pop_front(); |
| resize | changes the number of elements stored (public member function) void resize (size_type n); void resize (size_type n, const value_type& val); |
| swap | swaps the contents (public member function) void swap (deque& x); |
Reference
[1]《STL源码剖析》候捷
[2]C++ STL 体系结构与内核分析--从平地到万丈高楼-----候捷视频课程,https://www.bilibili.com/video/av45108908
浙公网安备 33010602011771号