标准库vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象,vector也叫容器。
C++既有类模板,也有函数模板,vector属于类模板。对于类模板来说,我们通过提供一些额外信息来指定模板到底实例化成什么样的类。以vector为例,提供的额外信息是vector内所存放对象的类型:
vector<int> ivec; //ivec保存int类型的对象
vector<Person> pvec; //保存Person类型的对象
vector<vector<string>>; //该向量的元素是vector类型
vector能容纳绝大部分对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector。需要指出的是,在早期版本的C++标准中,如果vector的元素还是vector,则其定义形式与现在的C++11新版本略有不同。过去,必须在外层vector对象的右尖括号和其元素之间添加一个空格,比如vector<vector>应该写成vector<vector >。
1.定义和初始化vector
下面列出来常用的定义vector的方法:
定义 | 描述 |
---|---|
vector v1 | v1是个空的vector,它的元素是T类型,执行默认初始化 |
vector v2(v1) | v2中包含v1所有元素的副本 |
vector v2=v1 | 等价于v2(v1) |
vector v3(n,val) | v3中包含了n个元素,每个元素的值都是val |
vector v4(n) | v4包含了n个重复地执行了初始化的对象 |
vector v5{a,b,c…} | v5包含了初始个数的元素,每个元素被赋予相应的初始值 |
vector v5={a,b,c…} | 等价于v5{a,b,c…} |
列表初始化vector
C++新标准还提供了另外一种为vector初始化的方法,即列表初始化。此时,用花括号扩起来的0个或多个初始元素值被赋给vector对象,比如v5。如果提供的是初始值列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在圆括号里。
创建指定数量的元素
还可以用vector对象容纳的元素数量和所有元素的统一初始值来初始化vector对象,比如v3。
列表初始值还是元素数量
在某些情况下,初始化的真实含义依赖于传递初始值时用的是花括号还是圆括号。如果是圆括号,可以说提供的值是用来构造vector对象的。如果是花括号,可以表述成我们想要列表初始化该vector对象:
vector<int> v1(10); //v1有10个元素,每个元素的值都是0
vector<int> v2{10}; //v1有1个元素,该元素的值是10
vector<int> v3(10,1); //v3有10个元素,每个元素的值是1
vector<int> v4{10,1} //v4有2个元素,值分别是10和1
另一方面,如果初始时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了:
vector<string> v5{"hi"}; //列表初始化:v5有一个元素,其值是"hi"
vector<string> v6("hi"); //错误,不能使用字符串字面值构建vector对象
vector<string> v7{10}; //因为10无法初始化string对象,所以花括号初始化变成了圆括号初始化,v7有10个默认初始化的元素
vector<string> v8{10, "hi"}; //同v7,10不能初始化string对象,v8有10个值为"hi"的元素
2.向vector对象中添加元素
vector提供了push_back方法用于把一个值当成vector对象的尾元素“压到”vector对象的“尾端”:
vector<int> v; //空vector对象
for(auto i=0; i!=100; ++i)
{
v.push_back(i); //依次把整数值放到v的尾端
}//循环结束后v有100个元素,值从0到99
需要注意,如果循环体内包含有向vector对象添加元素的语句,则不能使用范围for循环。
3.其他vector操作
操作 | 描述 |
---|---|
v.empty() | 判断v是否为空 |
v.size() | 返回v中元素的个数 |
v.push_back(t) | 向v的尾端添加一个值为t的元素 |
v.[n] | 返回v中第n个位置上元素的引用 |
v1=v2 | 用v2中的元素拷贝替换v1中的元素 |
v1 = {a,b,c…] | 用列表中的元素拷贝替换v1中的元素 |
v1==v2 | 当v1和v2元素数量相同并且对应位置的元素值相同是返回true,否则返回false |
v1!=v2 | 当v1和v2元素数量相同并且对应位置的元素值相同是返回true,否则返回false |
<,=,>,>= | 以字典顺序进行比较 |
vector对象的下标运算符可用于访问已存在的元素,而不能用于添加元素。试图用下标的形式去访问一个不存在的元素将引发错误,不过这错误不会被编译器发现,而是在运行时产生一个不可预知的值,所谓缓冲区溢出指的就是这类错误。这也是导致PC及其它设备上应用程序出现安全问题的一个原因。