C++ 头文件系列(array)
注意,该头文件仅在C++11中标准才开始出现。
简介
与语言内置的数组一样, array类模版支持几乎所有内置数组包含的特性:
- 顺序的(sequence)
- 内存连续的(contiguous storage)
- 固定大小的(fixed-size)
那既然与内置数组一样,为什么还要定义这样一个模版呢?C++委员会是想造轮子吗(-_-)?当然不是!
为什么需要array?
array模版类实际上是内置数组的聚合,外加一层封装。正是由于这层接口,才使得数组能与STL接轨,真正成为一个container。
Container接口
- array::size
- array::back
- array::front
- array::empty
- array::fill
- ...
简单通用的array接口,让数组使用起来更加得心应手。 例如size()成员函数返回数组的大小,在内置数组中则只能查看数组定义或者借助外部函数。
Interator模式接口(姑且让我这么叫吧)
- array::begin
- array::end
- array::cbegin
- array::cend
- array::rbegin
- array::rend
- array::crbegin
- array::crend
解决语法不一致性
Iterator作为C++中沟通Algorithm与Container的桥梁,起着不可或缺的作用。然而内置类型不支持迭代器的概念,虽然对于算法来说有合适的重载能够解决这个问题,但在语法上存在明显的差别(vec为vector,arr为int数组):
for_each(vec.begin(), vec.end(), [](int i)
{
// something
});
for_each(arr, arr + 3, [](int i)
{
// something
});
其实不需要变量定义声明就可以猜到,vec是container而arr不是。 这也许会阻碍代码后期的重构与修改。使用array类模版的话就不会存在这种问题,统一的语法,多棒!
Bound Check
我们都知道,C++沿袭了C语言的设计,在access数组元素时不对数组变量进行边界检查。array解决了这个问题,在元素读写越界时会抛出异常。
差异性
与内置数组的差异
array与内置数组的一个明显的差异就是----允许空数组的定义。
至于为什么要允许这样一个特性,也许是:
- 让空数组保持遍历一致性。
- 让array容器隐式地支持清空(毕竟作为一个fixed-size container,它没有对应的clear操作)。
然而,空数组在语义上是不允许解引用的,因此在使用时规避那些需要解引用的操作。
与其他容器的差异
该方面的差异主要体现在swap成员函数上。就像我们知道的,其他容器调用swap函数时,为了保证高效,该函数实际上执行的操作相当于交换指向实际容器内容的指针。但是array的swap函数却是进行逐成员交换,这也许是为了保持与内置数组相同的性质----数组地址不可变。
出于上述语义上的差别,array与其他容器的迭代器,在swap后会有不同的结果(深色方框代表容器对象, 方框内文字代表容器内容; 箭头代表迭代器变量, 都指向头元素):
swap前:

swap后:

从图上看更为直接:
- array模版类对象只是交换了内容而已,两个迭代器的值都未变。
- 其他容器对象不仅交换了内容,连迭代器的关联性都改变了(实际上,迭代器的值(即关联的内容)也没变,但关联的对象变了)。
Tuple接口
array还提供了一套独特的tuple接口,使其能够像使用元组那样使用。 当然,这种可能性的前提是它本身就非常像元组。
这种特性是通过重载tuple接口的get函数,并且特化tuple_element和tuple_size类模版实现的。
C++ 头文件系列(array)的更多相关文章
- C++ 头文件系列(queue)
简介 这个头文件定义了两个跟队列有关的类----quque.priority_queue,分别实现的是队列 和 优先队列这两个概念. 但是与这两个类模版与其它类模版(vector.array等)最大的 ...
- C++ 头文件系列(vector)
简介 vector头文件包含vector的类模版以及该模版的显示特化版本vector< bool >. vector是C++容器库中非常通用的一种容器,如果你不知道该决定使用哪一种容器,或 ...
- C++ 头文件系列(ios)
1 简介 我们都知道,平时常用的那些标准流,诸如iostream.ofstream.ifstream等等,其实都是对应的basic_XXX模版的实例类. 而这些basic_XXX类模版又都是继承自同一 ...
- C++ 头文件系列(stack)
简介 该头文件只含有一个类模版stack, 它实现栈的概念,是一个容器适配器(说实话,在写这篇随笔之前我都不知道有这么个类模版). 栈 栈只有一个重要的特性: LIFO(last-in first-o ...
- C++ 头文件系列(map)
简介 该头文件包含两个概念相似的容器----map.multimap. 而这两个容器反映的概念就是 映射. 这两个容器 相同 的属性有: 关联性 映射 动态增长 键(Key)唯一性 这两个不相同的属性 ...
- C++ 头文件系列(unordered_map、unordered_set)
简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...
- C++ 头文件系列(iterator)
简介 该头文件围绕迭代器展开,定义了一系列与迭代器有关的概念,但最最最重要的一点就是----它和其它容器一起实现了C++容器的Iterator设计模式. Iterators are a general ...
- C++ 头文件系列 (algorithm)
简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何 ...
- C++ 头文件系列 (bitset)
简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小 ...
随机推荐
- SQL点滴34—SQL中的大小写
原文:SQL点滴34-SQL中的大小写 默认情况下,SQL Server不区分大小写,如果数据表TEST的TNAME列中有数据“abcd”和“Abcd”, 如果使用查询语句:select * from ...
- 纯Lambda实现斐波那契数列
还需要考虑溢出等问题,主要无事写着玩 Func<float, float, float> a = (arg1, arg2) => 0f;//init ; a = (lastNumbe ...
- Dotfuscator类重命名方法解析
Dotfuscator是专业的.NET程序代码混淆工具,拥有重命名.字符串加密.流程模糊.自定义规则和水印等功能,倍受开发人员喜爱.其中类重命名的使用方法非常普遍,涉及到既要保护代码信息,又要在以后能 ...
- 【通过操作指针,与指针做函数參数'实现字串在主串中出现的次数,然后将出现的部分依照要求进行替换
】
#include<stdio.h> #include<stdlib.h> int strTime(const char *str1, const char *str2, int ...
- solr连接数据库
solr与.net系列课程(三)solr连接数据库 solr与.net系列课程(三)solr连接数据库 上一章直接讲述的配置文件把大部分人看的很迷惑,大家都想听的是solr到底是怎么用的,好,这 ...
- ORACLE抽象数据类型
ORACLE抽象数据类型 *抽象数据类型*/1,抽象数据类型 概念包含一个或多个子类型的数据类型不局限于ORACLE的标准数据类型可以用于其他数据类型中 2,创建抽象数据类型 的语法(必须用NOT F ...
- [转载+实践理解]Android动画---如何正确使用平移动画(关于fillBefore和fillAfter的一点说明)(转载)
红色部分为自己的实践理解 如何实现将View向上平移自身高度一半的距离? TranslateAnimation translate = new TranslateAnimation( Animatio ...
- 开发使用混合式Winform模块
开发使用混合式Winform模块 1.Winform数据访问模式定义 传统的Winform程序模块:用于传统的数据库通讯获取数据,这种方式获取数据,方便快捷,可以用于常规的业务系统的场景,用于单机版软 ...
- Webapi备忘-20140109
r01的翻译系列:http://www.cnblogs.com/r01cn/category/428069.html 接收FROM数据 Webapi接收表单数据,如果有多个数据比如x=1&y= ...
- c#一个简单的实例告诉你,多继承还可以这么来
我想多继承,要怎么搞???我想你一定会说“接口”,那么你有没有遇到这样的问题,你需要在一个类中继承另外2个类的所有方法,你要怎么做呢???难道要Coyp实现代码?No,往下看... 定义一个空接口比如 ...