vector容器
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>都是数据类型。
vector对象的定义和初始化
vector类定义了好几种构造函数,用来定义和初始化vector对象。下表3-4列出了这些构造函数:
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个副本。 |
创建确定个数的元素
若要创建非空的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
可以用元素个数和元素值对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增长的效率高,在元素值已知的情况下,最好是动态地添加元素。这种增长方式不同于C语言中的内置数据类型,也不同于大多数其他编程语言的数据类型。特别地,如果读者习惯了C或Java的风格,由于vector元素连续存储,可能希望最好是预先分配合适的空间。但事实上,为了达到连续性,C++的做法恰好相反。
虽然可以对给定元素个数的 vector 对象预先分配内存,但更有效的方法是先初始化一个空 vector 对象,然后再动态地增加元素。
值初始化
如果没有给出元素的初始化式,那么标准库将提供一个值初始化的(value initialized)元素初始化式。