std::Deque使用总结

本文详细介绍了C++ STL容器Deque的特性,包括与Vector的异同,如两端快速插入删除、内存管理等。同时,讨论了Deque在哪些场景下更为适用,并列举了其构造、复制、销毁及各种操作。最后提到了Deque的异常控制情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Deque

  Deque与Vector非常相似,它也采用dynamic array进行管理,提供随机访问,同时具有与vector一模一样的接口。不同的是Deque的dynamic array头尾都是开放的,因此可以在两端进行快速的插入和删除。
在这里插入图片描述
  为了提供这种能力,deque通常实现了一种独立区块(a bunch of individual blocks),第一区块朝某一方向扩展,最末区块朝另一方向扩展。
在这里插入图片描述
  使用Deque之前,必须包含头文件<deque>

	#include<deque>

  其中,deque的类型在std命名空间std内一个class template为:

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

  和vector相同,这里的T是为了template表明元素类型的,而Allocator则是指定内存模型(memory model)。

Deque的能力

  Deque与Vector相比,有所相同,又有所不同,下面是两者的异同点:
  相同之处
  1.支持随机访问,迭代器均属于random-access iterator;
  2.基于中间位置的元素的移除和插入,速度都比较慢,因为要进行大量元素的移动和复制操作;
  3.vector所支持的接口在deque上都能使用,且具有相同的效果。

  不同之处
  1.两端都能够进行快速的插入和移除操作
  2.访问deque时,内部结构会多一个间接过程,因此元素的访问以及迭代器的动作会相比vector较慢
  3.迭代器需要在不同的区块间进行跳转,因此迭代器必须是smart_pointer,不能是寻常pointer;
  4.Deque不支持对容量大小的控制,需要特别注意的是,除了首尾两端,在任何地点安插或者删除元素都会导致pointer、reference和iterator的失效;
  5.Deque重新分配内存优于vector,因为其内部结构显示,deque重新分配内存的时候,不需要复制所有的元素;
  6.Deque会释放不需要的内存块,Deque的大小是可缩减的,但是要不要这么做,如何做,取决于编译器。
  总结:显然,deque具有vector的特性,且比vector更强大,但C++之中,更强大的功能往往意味这更大的时空开销,如何在功能和开销上作取舍,取决于具体应用场景。

  Deque适用场景
  1.移除和插入操作发生在首尾两端(Deque的特性决定了该操作效率惊人);
  2.无须迭代器指向其元素(Deque扩容机制导致了其迭代器更容易失效);
  3.要求不再使用的元素必须释放(Deque能够释放不使用的内存块,但C++ standard并不保证这一点,依赖于编译器实现)。

Deque相关操作

构造、复制和销毁

  Deque的构造与析构函数,设计逻辑与Vector几乎相同。

序号操作效果
1deque<Elem> cDeque默认构造函数,生成一个deque,没有任何元素
2deque<Elem> c(c2)
deque<Elem> c=c2
Copy构造函数,支持深度拷贝
3deque<Elem> c(rv)
deque<Elem> c=rv
Move构造函数,rv是右值引用(C++11新特性
4deque<Elem> c(n)生成一个大小为n的deque
5deque<Elem> c(n,elem)生成一个大的小为n的deque,并初始化元素为elem
6deque<Elem> c(beg,end)生成一个deque,以区间[beg,end)作为元素初值
7deque<Elem> c(initlist)生成一个deque,并以初值列进行初始化
8c.~deque()销毁所有元素,释放内存

非更易型操作(Nonmodifying Operating)

  与Vector相同,Deque的非更易型操作如下表所示:

序号操作效果
1c.empty()返回容器是否为空,为空则返回true,否则false
2c.size()返回目前元素的个数
3c.max_size()返回元素个数的最大可能量,即自动分配内存的极限
4c.shrink_to_fit()降低容量以符合元素个数(C++11新特性
5c1==c2
c1!=c2
c1>c2
c1<c2
c1<=c2
c1>=c2
容器的比较操作都是基于每个元素的,即所有的元素都满足比较关系才返回true,否则是false
6c[index]返回索引index所指向的元素(不检查边界)
7c.at(index)返回索引index所指向的元素(检查边界,越界会抛出range-error异常)
8c.front()返回第一元素
9c.back()返回最末元素
10c.begin()返回一个random-access iterator,指向第一个元素
11c.end()返回一个random-access iterator,指向最后一个元素
12c.cbegin()返回一个const random-access iterator,指向第一个元素(C++11新特性
13c.cend()返回一个const random-access iterator,指向最后一个元素(C++11新特性
14c.rbegin()返回一个reverse iterator,指向第一个元素
15c.rend()返回一个reverse iterator,指向最后一个元素
16c.crbegin()返回一个const reverse iterator,指向第一个元素(C++11新特性
17c.crend()返回一个const reverse iterator,指向最后一个元素(C++11新特性

  举个例子——

	deque<int> c{ 1,2,3,4,5,6,7,8,9 };
	cout << "c.empty() = " << c.empty() << endl
		<< "c.size() = " << c.size() << endl
		<< "c.max_size()" << c.max_size() << endl;
	for (auto it = c.cbegin(); it != c.cend(); it++) {
		cout << *it << " ";
	}

在这里插入图片描述

更易型操作

  Deque的更易型操作,如下表所示:

序号操作效果
1c = c2将c2的数据复制给c,该复制是深度复制
2c = rv将rvalue rv的所有元素以move assignment的形式给c(C++11新特性
3c = initlist将初值列所有元素赋值给c(C++11新特性
4c.assign(n,elem)复制n个elem元素给c
5c.assign(beg,end)复制区间[beg,end)元素给c
6c.assign(initlist)复制初值列所有元素给c
7c1.swap(c2)
swap(c1,c2)
置换c1和c2的数据
8c.push_back(elem)附加一个elem元素到deque末尾
9c.pop_back()移除末尾的一个元素,不返回任何值
10c.push_front()附加一个elem元素到首部
11c.pop_front()移除首部的一个元素,不返回任何值
12c.insert(pos,elem)在iterator指向的pos位置的前一个位置插入elem拷贝,并返回新元素的位置
13c.insert(pos,n,elem)在iterator指向的pos位置的前一个位置插入n个elem拷贝,并返回第一个新元素的位置
14c.insert(pos,beg,end)在iterator指向的pos位置的前一个位置插入区间[beg,end)所有元素拷贝,并返回第一个新元素的位置
15c.insert(pos,initlist)在iterator指向的pos位置的前一个位置插入initlist初值列拷贝,并返回第一个新元素的位置(C++11新特性)
16c.emplace(pos,args…)在iterator位置pos之前插入一个以args为初值的运输,并返回新元素的位置(C++11新特性
17c.emplace_back(args…)插入一个args初值于末尾,不返回任何东西(C++11新特性
18c.emplace_front(args…)插入一个args初值于首部,不返回任何东西(C++11新特性
19c.erase(pos)移除iterator位置pos的元素,返回下一个元素的位置
20c.erase(beg,end)移除区间[beg,end)区间内的所有元素,返回下一个元素的位置
21c.resize(num)将元素数量大小调整为num,如果数量比原始要大,那么多出来的部分用默认构造函数进行初始化
22c.resize(num,elem)将元素数量大小调整为num,如果数量比原始要大,那么多出来的部分用初始化为elem
23c.clear()移除所有元素,释放内存

异常控制

  Deque提供的异常处理是STL所定义的最低限度的异常处理,除了at函数会对边界进行检查,可能会抛出range-error异常之外,其他函数不会抛出任何标准异常,但编译器往往会加入自己的异常处理,比如VS所实现的STL版本就有诸多异常控制。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值