C++ 头文件系列(vector)
简介
vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >。
vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或者没有足够的理由使用其它容器,那么就用它,没错的!
从整体上来看,vector就像是一种动态数组,它拥有数组的所有功能并且能够动态增长。 它主要有以下性质:
- 序列性容器
- 动态增长
- 可定制的内存分配策略
内存分配器
如果在一些特殊的应用场景中,默认的内存分配策略拉低了运行效率,这时候自定义的内存分配其就会站出来帮你了~
内存分配器主要用在STL Containers中,为容器合理的分配内存,默认使用位于memory头文件中的allocator。 我们也可以自定义内存分配器,但需要满足一些要求:
Other allocators may be defined. Any class Alloc for which allocator_traits produces a valid instantiation with the appropriate members defined can be used as an allocator on standard containers (Alloc may or may not implement the functionality through member functions).
上面这段摘录的文字表明,任何能够实例化allocator_traits模版并且带有合适成员函数的类Alloc都能作为容器的内存分配器使用。 再来看allocator_traits:
The non-specialized version provides an interface that allows to use as allocator just any class that provides at least a public member type value_type and public member functions allocate and deallocate (see example).
这段话说,任何至少提供了一个公开成员类型value_type和公开成员函数allocate和deallocate的类都可以被允许作为内存分配器。
总的来说,自定义一个内存分配器,你最少需要:
- 定义value_type类型
- 定义allocate成员函数
- 定义deallocate成员函数
特殊函数
由于vector是动态数组,它的大部分设计是与array类模版类似的,这里就不再赘述了。 我们来看看那些不一样的的地方。
resize VS shrink_to_fit
这两个函数是比较特别的,从字面上看它们都是改变大小为固定值。 但实际上两者是有区别的,我们来看它们的函数原型:
void resize (size_type n);
void shrink_to_fit ();
一眼就能看出,两者的参数不一样:resize传入一个数值,作为新的容器大小;而shrink_to_fit则没有参数。 那我们不禁要问了,既然shrink_to_fit没有指定新的容器大小,它怎么改变呢?
这就揭示了两者语义上的不同----一个是改变大小至给定值,另一个是缩小容器容量(capacity)至容器大小(size)。 也就是说,它们影响的是容器的两个不同方面。 同时需要指出的是, shrink_to_fit调用发出的是请求,调用后容器容量可能被按预期缩小到容器大小了,也有可能比容器大小大;而resize调用发出的时命令,容器一定会被重新调整大小至给定值。
C接口
vector提供了一个接口以供开发者直接在内部数组(vector内部以数组实现)上直接对元素进行操作:
- value_type* data() noexcept;
顺道一提,vector与array一样,是元素之间的内存连续的(contiguous)。
vector< bool >显示特化
非常有意思的是vector这个模版显示特化了。
为什么
为什么会出现这样一个特殊的模版特化呢? 因为语言支持的最小单位一般是字节(char、unsigned char),而bool的语义意味着它只需要1bit的内存。 如果用1个字节来存储bool类型,会造成极大的内存浪费,出于内存的优化考虑,就出现了这么一个特殊的东西。
它的原理非常简单,就是把每个bool用1个bit来存储,所以1个字节可以存储8个bool(在常见的机器上)。 但是这也引出了一个麻烦的问题:在语义上,我们应该可以对bool赋值、取地址、取引用等。 但是bool等于bit这种实现方式意味着我们不能够那样做。 那怎么办了,这里使用了一个C++典型的惯用法----代理(Proxy),它把reference成员理性定义为该代理,用这个代理来将内部bit转换成bool。
Flip函数
该模版特化还包含了一个额外的函数----Flip。 顾名思义,就是将所有bool都“翻转”,true -> false, false -> true。
先前提到的reference代理也有这个函数,但它是将单个bool“翻转”。 vector< bool >类模版的flip函数可能就是通过该函数实现的。
C++ 头文件系列(vector)的更多相关文章
- C++ 头文件系列(array)
注意,该头文件仅在C++11中标准才开始出现. 简介 与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性: 顺序的(sequence) 内存连续的(contiguous stora ...
- C++ 头文件系列(queue)
简介 这个头文件定义了两个跟队列有关的类----quque.priority_queue,分别实现的是队列 和 优先队列这两个概念. 但是与这两个类模版与其它类模版(vector.array等)最大的 ...
- C++ 头文件系列(map)
简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...
- C++ 头文件系列 (bitset)
简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小 ...
- C++ 头文件系列(iosfwd)
简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...
- C++ 头文件系列(stack)
简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...
- C++ 头文件系列(unordered_map、unordered_set)
简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...
- C++ 头文件系列(iterator)
简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...
- C++ 头文件系列 (algorithm)
简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何 ...
随机推荐
- 【HighCharts系列教程】十、图例属性——legend
一.legend属性说明 Legend是HighCharts图表的图例属性,如图 默认情况下,HighCharts都会有图例,无特殊情况,默认即可满足需求,所以一般不用配置Legend属性. 二.la ...
- Bootstrap-dialog的使用(续Bootstrap Table)
Bootstrap-dialog实现表格内容的增,删,改. 插件引入:必须先引入jquery和bootstrap和artTemplate. <link rel="stylesheet& ...
- centos 7用ss命令来查看端口占用和对应进程
mysqld进程在监听4567端口,进程id是2593:# ss -lnp|grep 4567tcp LISTEN 0 128 *:456 ...
- SQL复习一(基础知识)
1.什么是sql SQL(structure query language)是结构化查询语言,它是对关系型数据库的操作语言.它可以应用到所有的数据库中,例如:MySQL.Oracle.SQL serv ...
- ARM-LINUX学习笔记-(虚拟机linux串口终端以及USB程序下载,基于TQ2440)
昨天安装了ssh服务之后今天在windows上用xshell登陆发现登录不上,原因是使用了virtualbox的NAT模式,在NAT模式下,客户机可以很方便地上网,但是想要链接宿主机就需要打开网络地址 ...
- (一)Javascript基础知识
一,五种基本数据类型和一种复合数据类型. 五种基本数据类型 1,undefined 2,null 3,string 4,number 5,boolean 6,复合数据类型(Object,Array,D ...
- AForge.NET是一个专门为开发者和研究者基于C#框架设计的视频录像
AForge.NET是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域.这个框架由一系列的类库组成.主要包括有 ...
- 避免Node.js中回调地狱
为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务. downloadFile('example. ...
- DDD设计一个电商网站
DDD设计一个电商网站(十一)-- 最后的准备 阅读目录 前言 准备 实现 结语 一.前言 最近实在太忙,上周停更了一周.按流程一步一步走到现在,到达了整个下单流程的最后一公里--结算页的处理. ...
- CSS3 :target伪类实现Tab切换效果 BY commy
http://www.shejidaren.com/examples/css3-target/css3-target.html#tab1 标签一 标签二 标签三 欢迎加设计达人Q群:50063010设 ...