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

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对象,元素的值为val
	
template <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/107751785https://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/107751785https://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/107427911https://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/107427911https://blog.csdn.net/Master_Cui/article/details/107573300https://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/107427911https://blog.csdn.net/Master_Cui/article/details/107573300https://blog.csdn.net/Master_Cui/article/details/107751785

6.deque的交换

void swap (deque& x);

同vector与list

见博客https://blog.csdn.net/Master_Cui/article/details/107427911https://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

 

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值