13.2 使用序列式容器

    容器是STL的基础,容器有序列式容器(Sequential Container)和关联式容器(Associative Container)之分。总体来说,序列式容器会强调元素的次序,依次维护第一个元素到最后一个元素,面向序列式容器的操作主要是迭代操作,本节讨论序列式容器vector、list和deque的用法,以及序列式容器的共同操作。

    13.2.1 序列式容器的创建和元素的访问

    要使用序列式容器,必须包含相关的头文件,vector、list以及deque分别对应于如下头文件。


    #include<vector> #include<list> #include<deque>

    创建序列式容器的对象,大体有以下几种方式。

    (1)创建空的容器,此时容器中的元素个数为0。


    vector<int>obV; list<float>obL; deque<double>obD;(2)产生特定大小的容器,此时容器中的元素被创建,但未被显式初始化,编译器使用默认值为元素隐式初始化,像int、float和double等内置的数据类型会被初始化为0。对于类对象元素,将调用其无参构造函数(用户定义的或编译器默认提供的)或每个参数都有默认值的构造函数。如下所示。 vector<double>obV(50);//vector型对象obV中含50个double型的元素,初始化为0 list<int>obL(1000);//list型对象obL中含1000个int型元素,初始化为0 deque<float>obD(2);//deque型对象obD中含2个float型元素,初始化为0

    (3)在(2)的基础上,创建特定大小的容器,并且为其中的每个元素指定初始值,此时在元素的参数后增加一个参数,如下所示。


    vector<int>obV(10,8);//10个int型元素,每个都初始化为8 list<double>obL(5,3.2);//5个double型元素,每个都初始化为3.2 deque<string>obD(100,"Hello");//100个string型元素,每个都初始化为“Hello”

    (4)根据已有同类型的容器创建新容器,并将其中的元素完全复制过来,设obV1、obL1和obD1都是现成的容器,里面存储的数据均为int型,则可用下述命令创建新容器。


    vector<int>obV2(obV1);//或vector<int>obV2=obV1; list<int>obL2(obL1);//或list<int>obL2=obL1; deque<int>obD2(obD1);//或deque<int>obD2=obD1;

    (5)通过一对迭代器(可暂时理解为指针),使编译器决定元素的个数和初始值,这对迭代器用以标识一组元素区间。


    int sz[5]={1,2,3,4,5}; vector<int>obV(sz,sz+5); list<int>obL(sz,sz+5); deque<int>obD(sz,sz+5);

    容器创建完毕后,便可以通过“容器名[下标]”或“容器名.at(序号)”的形式对vector和deque中的元素进行随机访问,这是因为在vector和deque类模板中已经对下标运算符进行了重载,返回类型便是其中存储的数据类型。同数组一样,元素的初始下标为0,而且编程时同样要注意下标越界问题。此外,还可以通过迭代器对vector和deque中的元素进行间接访问,在迭代器一节中会进行具体的介绍,但对list来说,其不支持下标运算符访问方式(数组表示法),也就是说无法对list中的元素进行随机访问,必须通过迭代器来进行。如示例代码13.1所示。

    代码13.1 容器的创建与其中元素的访问CreateAndContainer


    <————————————文件名:example1301.cpp——————————————-> 01 #include<iostream> 02 #include<vector> 03 #include<list> 04 #include<deque> 05 using namespace std; 06 int main() 07 { 08 vector<int>obv;//创建一个空的vector 09 cout<<"obv的元素个数为:"<<obv.size()<<endl;//size()用以返回元素的个数 10 double sz[5]={1,2,3,4,5};//创建double型数组sz 11 deque<double>obD(sz,sz+5);//创建deque型容器obD,用sz的 12 //首地址和(末地址+1)初始化,方式5 13 for(unsigned int i=0;i<obD. size();i++)//对obD中的元素进行随机访问 14 { 15 cout<<obD[i]<<"";//下标表示法或obD.at(i) 16 } 17 cout<<endl;//换行 18 list<float>obL(3,5);//创建一个大小为3的list型容器obL, 19 //其中每个元素都初始化为5 20 list<float>:iterator iter=obL. begin();//创建list<float>型迭代器,类似指针的 21 //概念,并使其指向obL的第1个元素 22 while(iter!=obL. end())//while结构,直到iter指向obL的尾部 23 { 24 cout<<(*iter)<<"";//通过迭代器间接访问容器中的元素 25 iter++;//指向下一个元素 26 } 27 cout<<endl;//换行 28 return 0; 29 }

    输出结果如下所示。


    obv的元素个数为:0 1 2 3 4 5 5 5 5

    【代码解析】代码中演示了3种容器的创建及其元素的访问过程,值得注意的是对代码第18行的list型容器对象obL,不能使用诸如“obL[1]”之类的下标运算符和诸如“obL.at(1)”的形式访问其中的元素,只能借助于迭代器的间接访问。

    代码13.1 初步演示了迭代器的用法,从表面上看迭代器类似于指针,迭代器的声明格式如下所示。


    容器类型<class type>:iterator迭代器对象名;

    这只是迭代器的一种形式,稍后会有更详细的介绍。