vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值.
和string对象一样,标准库将负责管理与存储元素相关的内存.我们把vector称为容器,是因为它可以包含其他对象.一个容器中的所有对象都必须是同一种类型.
使用vector之前,必须包含相应的头文件.
#include<vector>
using std::vector;
vector是一个类模板(class template).使用模板可以编写一个类定义或函数定义,而用于多个不同的数据类型.因此,我们可以定义保存string对象的vector,或保存int值的vector,又或是保存自定义的类类型对象(如Sales_item对象)的vector.
幸运的是,使用类模板时只需要简单了解类模板是如何定义的就可以了.
声明从类模板产生的某种类型的对象,需要提供附加信息,信息的种类取决于模板.以vector为例,必须说明vector保存何种对象的类型,通过将类型放在类模板名称后面的尖括号中来指定类型:
vector<int> ivec; //ivec holds objects of type int
vector<Sales_item>Sales_vec; //holds Sales_items
和其他变量定义一样,定义vector对象要指定类型和一个变量的列表.上面的第一个定义,类型是vector<int>,该类型即是含有若干int类型对象的vector,变量名为ivec.第二个定义的变量名是Sales_vec,它所保存的元素是Sales_item类型的对象.
注解:vector不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型.vector类型的每一种都制定了其保存元素的类型.因此,vector<int>和vector<string>都是数据类型.
3.3.1vector对象的定义和初始化
vector类定义了好几种构造函数,用来定义和初始化vector对象.下面列出了这些构造函数.
vector<T>v1; vector保存类型为T的对象.默认构造函数v1为空.
vector<T>v2(v1); v2是v1的一个副本.
vector<T>v3(n,i); v3包含n个值为i的元素.
vector<T>v4(n); v4含有值初始化的元素的n个副本.
1.创建确定个数的元素
若要创建非空的vector对象,必须给出初始化元素的值.当把一个vector对象复制到另一个vector对象时,新复制的vector中每一个元素都初始化为原vector中相应元素的副本.但这两个vector对象必须保存同一种元素类型:
vector<int>ivec1; //ivec1 holds objects of type int
vector<int>ivec2(ivec1); //ok:copy elements of ivec1 into ivec2
vector<string>svec(ivec1); //error:svec holds strings,not ints
可以看出,参与复制的两个对象必须保存同一种元素类型,而且我们可以留意一下变量的命名.int的,i+vec(vector).string的,s+vec(vector)
可以利用元素个数和元素值对vector对象进行初始化.构造函数用元素个数来决定vector对象保存元素的个数,元素值制定每个元素的初始值:
vector<int>ivec4(10,=1); //10 elements,each initialized to -1
vector<string>svec(10,"hi!"); //10 strings,each initialized to "hi!"
关键概念:vector对象动态增长
vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素.因为vector增长的效率高,在元素值已知的情况下,最好是动态地添加元素.
小心:虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素(我们随后将学习如何进行这样的操作).
2.值初始化
如果没有制定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化(value initialization).这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何(具体值是什么),取决于存储在vector中元素的数据类型.
如果vector保存内置类型(如int类型)的元素,那么标准库将用0值创建元素初始化式:
vector<string>fvec(10); //10 elements each initialized to o
如果vector保存的是含有构造函数的类类型(如string)的元素,标准库将用该类型的默认构造函数创建元素初始化式:
vector<string>svec(10); //10 elements,each an empty string
注解:不久会介绍一些有自定义构造函数但没有默认构造函数的类,在初始化这种类型的vector对象时,程序员就不能仅提供元素个数,还需要提供元素初始值.
还有第三种可能性:元素类型可能是没有定义任何构造函数的类类型.这种情况下,标准库仍产生一个带初始值的对象,这个对象的每个成员进行了值初始化.
习题3.11下面哪些vector定义不正确?
a.vector<vector<int>>ivec;b.vector<string>svec=ivec;
c.vector<string)svec(10,"null");
令人诧异,不正确的并不是a.而是b.
a中的ivec是保存vector<int>对象的vector对象(即ivec是vector的vector),而b中svec是定义为保存string对象的vector对象.二者数据类型不一样,不能用ivec来初始化svec.
习题3.12 下列每个vector对象中元素个数是多少?各元素的值是什么?
a.vector<int>ivec1;
b.vector<int>ivec2(10);
c.vector<int>ivec3(10,42);
d.vector<string>svec1;
e.vector<string>svec2(10);
f.vector<string>svec3(10,"hello");
a.0个
b.10个,数值均为0
c.10个,数值均为42.
d.0个
e.10个,值均为空字符串.
f.10个,值均为"hello".