deque容器是双端队列,使用前,需要添加#include <deque>

deque的内存结构如下:

根据上图可知,deque和vector,string稍有不同,deque的内存是分段连续内存结构,所以,deque的内存在增长的时候,也是分段增长的,不会像vector那样复制所有元素,然后重新分配内存,所以不存在预分配空间,所以就没有capacity函数,但是仍然存在预分配内存的情况,所以仍然有shrink_to_fit函数来使内存空间大小和元素个数相匹配。

正是由于分段增长内存,所以当一段内存中不存储deque的元素时,deque会自动将那一段内存释放。

也正是由于内存的分段,所以访问元素和使用迭代器的时候,会比vector和string稍慢(因为迭代器要在不同段的内存跳跃)

1.deque的初始化

explicit deque (const allocator_type& alloc = allocator_type());//默认构造函数,默认初始化调用explicit deque (size_type n);//一般构造函数,创建一个含有n个元素的deque对象,元素的默认值为0或者默认对象
explicit deque (size_type n, const value_type& val,const allocator_type& alloc = allocator_type());//一般构造函数,创建一个含有n个元素的deque对象,元素的值为valtemplate <class InputIterator>deque (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type());//使用迭代器表示的元素范围进行初始化deque (const deque& x);//拷贝初始化
deque (const deque& x, const allocator_type& alloc);deque (initializer_list<value_type> il,const allocator_type& alloc = allocator_type());//列表初始化

上面的构造函数和拷贝构造函数类似list和vector

可参考博客https://blog.csdn.net/Master_Cui/article/details/107751785和https://blog.csdn.net/Master_Cui/article/details/107427911

2.deque的赋值

void assign (InputIterator first, InputIterator last);
void assign (size_type n, const value_type& val);
void assign (initializer_list<value_type> il);

类似list和vector

可参考博客https://blog.csdn.net/Master_Cui/article/details/107751785和https://blog.csdn.net/Master_Cui/article/details/107427911

3.deque的访问

reference at (size_type n);
const_reference at (size_type n) const;reference back();
const_reference back() const;reference front();
const_reference front() const;

由于deque的内存结构和vector与string类似,所以支持下标访问和at函数

front和back函数的用法同vector与string

见博客https://blog.csdn.net/Master_Cui/article/details/107427911和https://blog.csdn.net/Master_Cui/article/details/107573300

4.deque的添加

因为是双端队列,所以在头尾都可以添加元素,所以同时支持push_back和push_front

void push_back (const value_type& val);
void push_front (const value_type& val);

用法同list

deque也有insert方法

iterator insert (const_iterator position, const value_type& val);iterator insert (const_iterator position, size_type n, const value_type& val);template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);iterator insert (const_iterator position, initializer_list<value_type> il);

用法同vector,string与list

见博客https://blog.csdn.net/Master_Cui/article/details/107427911,https://blog.csdn.net/Master_Cui/article/details/107573300,https://blog.csdn.net/Master_Cui/article/details/107751785

5.deque的删除

void pop_front();
void pop_back();
iterator erase (const_iterator position );
iterator erase (const_iterator first, const_iterator last );

用法和示意同vector,string与list

见博客https://blog.csdn.net/Master_Cui/article/details/107427911,https://blog.csdn.net/Master_Cui/article/details/107573300,https://blog.csdn.net/Master_Cui/article/details/107751785

6.deque的交换

void swap (deque& x);

同vector与list

见博客https://blog.csdn.net/Master_Cui/article/details/107427911与https://blog.csdn.net/Master_Cui/article/details/107751785

7.deque的迭代器失效

因为deque的内存结构是分段连续的,所以,除了头尾两端,在deque对象的其他位置删除,添加元素,会导致迭代器失效

示例1

void iterfailed()
{deque<int> d1={1,2,3,4,5,6};deque<int>::iterator it=d1.begin()+3;d1.insert(d1.begin(), 0);cout<<*it<<endl;
}

可见,添加元素之后,保存的迭代器失效了

示例2

void iterfailed()
{deque<int> d1={1,2,3,4,5,6};deque<int>::iterator it=d1.begin()+3;d1.erase(d1.begin()+4);cout<<*it<<endl;
}

erase同理

再就是在erase和insert后,没有更新迭代器

示例

void iterfailed()
{deque<int> d1={1,2,3,4,5,6};deque<int>::iterator it=d1.begin()+3;//it=d1.erase(it);d1.erase(it);cout<<*it<<endl;
}

insert同理

最后就是因为逻辑不严谨,导致可能解引用尾后迭代器

示例

void iterfailed2()
{deque<int> d1={1,2,3,4,5,6};deque<int>::iterator it=d1.begin();while(it!=d1.end()) {if (*it %2==0) {it=d1.erase(it);}cout<<*it<<endl;++it;}
}

解决办法参照博客https://blog.csdn.net/Master_Cui/article/details/107503634

因为deque不会重新分配内存,所以也就不会出现像vector和string那样重新分配内存而导致迭代器失效的情况

总之,deque迭代器失效的原因和vector类似,主要如下:

1.除了头尾两端,在deque对象的其他位置删除,添加元素,会导致迭代器失效

2.erase和insert后,没有更新迭代器

3.逻辑不严谨,导致可能解引用尾后迭代器

参考

《C++ Primer》

《C++标准库》

http://www.cplusplus.com/reference/deque/deque/

https://www.bilibili.com/video/BV1db411q7B8?p=18

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

C++知识点24——使用C++标准库(顺序容器deque的初始化,赋值,访问,添加,删除,交换与迭代器失效)相关推荐

  1. C++知识点25——使用C++标准库(容器适配器stack、queue、priority_queue)

    除了vector,list,deque等常用的容器,还有根据这些常用的容器进行改造来满足特殊要求的容器,这些特殊容器的行为和常用容器很相近,也称为容器适配器. 常用的容器适配器有三个,分别是stack ...

  2. C++知识点19——使用C++标准库(再谈string——string的初始化、赋值、添加、删除、访问)

    1.string的构造函数 string();//默认构造函数,默认初始化时调用 string (const string& str);//拷贝构造函数,拷贝初始化时调用 string (si ...

  3. C++知识点30——使用C++标准库(关联容器map及其初始化,赋值,查找,添加,删除与迭代器失效)

    一.关联容器简介 关于顺序容器和关联容器的区别已经在博客https://blog.csdn.net/Master_Cui/article/details/107427911中提过 C++标准库中的关联 ...

  4. C++知识点23——使用C++标准库(顺序容器list的其他操作)

    除了博客https://blog.csdn.net/Master_Cui/article/details/107751785中介绍的操作,list还有一些其他的操作 1.reverse void re ...

  5. C++知识点22——使用C++标准库(顺序容器list的初始化、赋值、访问、交换、添加、删除与迭代器失效)

    list容器是双向链表,使用前,需要添加#include <list> 1.list的初始化 常用的构造函数如下 explicit list (const allocator_type&a ...

  6. C++知识点17——使用C++标准库(顺序容器vector常用操作)

    C++STL中的容器类型分为两种,一种是顺序容器,另一种是关联容器,这两种容器之所以被划分,本质区别是顺序容器可以通过元素在容器中的位置进行访问及存储,而关联容器只能通过键来访问和存储元素 顺序容器常 ...

  7. C++知识点32——使用C++标准库(关联容器set和multiset的初始化,赋值,查找,添加,删除与迭代器失效)

    关联容器map和multimap已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877和https://blog.csdn.ne ...

  8. C++知识点31——使用C++标准库(关联容器multimap及其初始化,赋值,查找,添加,删除与迭代器失效)

    关于关联容器map已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877中介绍完了 multimap和map非常类似,容器中的元 ...

  9. C++知识点33——使用C++标准库(无序关联容器unordered_(multi)map,unordered_(multi)set)

    C++中,无序关联容器一共有4个,unordered_map,unordered_set,unordered_multimap,unordered_multiset 这四个和有序关联容器最大的区别就是 ...

最新文章

  1. 数字图像恢复matlab结论,matlab 模糊图像恢复 数字图像处理
  2. python入门第一课_入门第一课 Python入门涉及的问题及简单示例
  3. matlab三维feather,matlab高维图形,别地方抄来的
  4. 微软Azure予力Green Dot客服成就不凡
  5. Python学习笔记——基础篇【第七周】———FTP作业(面向对象编程进阶 Socket编程基础)...
  6. memcached 如果进程占用cpu很高
  7. 垃圾图像分类,街景图像识别!华为云AI主题赛火热招募中!
  8. 国家存储器基地项目二期于武汉开工 月规划产能20万片
  9. fatal error: hb.h: 没有那个文件或目录
  10. EHIGH恒高:大话UWB技术之蓝牙定位的烦恼
  11. Git客户端精简版Git-2.10.0-32-bit.exe
  12. amesim子模型_为什么amesim模型建立后有的元件没有可用的子模型
  13. html中怎样写渐变色代码,html颜色渐变代码 怎样用css实现网页背景颜色渐变
  14. Redis介绍 AND SpringBoot集成Redis
  15. 团队作业8----第二次项目冲刺(Beta阶段) 第一天
  16. FACES纳新|2021春纳线上分享会等你来
  17. 北京办理居住证的全流程
  18. java指定图片的dpi和存储大小kb
  19. 用今天的坚强,救赎曾经迷失的自己
  20. 张小龙2019微信公开课15个看点总结

热门文章

  1. Mac 安装md5sum等
  2. eclipse从数据库逆向生成Hibernate实体类
  3. Python开发环境Wing IDE如何设置Python路径
  4. 基于Python的BPSK音频的波形和频谱
  5. SpringBoot启动类的扫描注解的用法及冲突原则
  6. while循环,递进,linux按行读入并按数组存储
  7. Ubuntu中如何使得程序在后台运行
  8. java - 第一阶段总结
  9. js 倒计时 时间戳
  10. WP8.1学习系列(第二十五章)——控件样式