C++头文件系列(vector)

发表于:2017-1-25 09:47

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:lgxZJ    来源:51Testing软件测试网采编

  简介
  vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >。
  vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或者没有足够的理由使用其它容器,那么就用它,没错的!
  从整体上来看,vector就像是一种动态数组,它拥有数组的所有功能并且能够动态增长。 它主要有以下性质:
  · 序列性容器
  · 动态增长
  · 可定制的内存分配策略
  内存分配器
  如果在一些特殊的应用场景中,默认的内存分配策略拉低了运行效率,这时候自定义的内存分配其就会站出来帮你了~
  内存分配器主要用在STL Containers中,为容器合理的分配内存,默认使用位于memory头文件中的allocator。 我们也可以自定义内存分配器,但需要满足一些要求:
  Other allocators may be defined. Any class Alloc for which allocator_traits
  上面这段摘录的文字表明,任何能够实例化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函数可能就是通过该函数实现的。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号