模板类vectorc++
模板类vector相似于string类,也是一种动态数组。您能够在运行阶段设置vector对象的长度,可在末尾附加新数据,还可在中间插入新数据。基本上,它是使用new建立动态数组的替代品。实际上,vector类确实使用new和delete来管理内存,但这种工做是自动完成的。数组
这里不深刻探讨模板类意味着什么,而只介绍一些基本的实用知识。首先,要使用vector对象,必须包含头文件vector。其次,vector包含在名称空间std中,所以您可以使用using编译指令、using声明或std::vector。第三,模板使用不一样的语法来指出它存储的数据类型。第四,vector类使用不一样的语法来指定元素数。下面是一些示例:安全
#include<vector> ... using namespace std; vector<int> vi; int n; cin>>n; vector<double> vd(n);
其中,vi是一个vector<int>对象,vd是一个vector<double>对象。因为vector对象在您插入或添加值时自动调整长度,所以能够将vi的初始长度设置为零。但要调整长度,须要使用vector包中的各类方法。函数
通常而言,下面的声明建立一个名为vt的vector对象,它可存储n_elem个类型为typeName的元素:spa
vector<typeName> vt(n_elem); c++11
其中参数n_elem能够是整型常量,也能够是整型变量。code
模板类array(C++11)对象
vector类的功能比数组强大,但付出的代价是效率稍低。若是您须要的是长度固定的数组,使用数组是更佳的选择,但代价是不那么方便和安全。有鉴于此,C++11新增了模板类array,它也位于名称空间std中。与数组同样,array对象的长度也是固定的,也使用栈(静态内存分配),而不是自由存储区,所以其效率与数组相同,但更方便,更安全。要建立array对象,须要包含头文件array。array对象的建立语法与vector稍有不一样:blog
#include <array> ... using namespace std; array<int ,5> ai; array<double,4> ad={1.2,2.1,3.43,4.3};
推而广之,下面的声明建立一个名为arr的array对象,它包含n_elem个类型为typename的元素:索引
array<typeName,n_elem> arr;
与建立vector对象不一样的是,n_elem不能是变量。
在C++11中,可将列表初始化用于vector和array对象,但在C++98中,不能对vector对象这样作。
比较数组、vector对象和array对象
要了解数组、vector对象和array对象的类似和不一样之处,最简单的方式多是看一个使用它们的简单示例
int main() { double a1[4] = { 1.2,2.4,3.6,4.8 }; vector<double> a2(4); //建立含4个元素的vector a2[0] = 1.0 / 3.0; a2[1] = 1.0 / 5.0; a2[2] = 1.0 / 7.0; a2[3] = 1.0 / 9.0; //c++11--建立并初始化数组对象 array<double, 4> a3 = { 3.14,2.72,1.62,1.41 }; array<double, 4> a4; a4 = a3; //数组对象大小相同时可赋值 //用数组表示法 cout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl; cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl; cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl; cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl; a1[-2] = 20.2; cout << "a1[-2]: " << a1[-2] << " at " << &a1[-2] << endl; cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl; cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl; return 0; }
程序说明
首先,注意到不管是数组、vector对象仍是array对象,均可使用标准数组表示法来访问各个元素。其次,从地址可知,array对象和数组存储在相同的内存区域(即栈)中,而vector对象存储在另外一个区域(自由存储区或堆)中。第三,注意到能够将一个array对象赋给另外一个array对象;而对于数组,必须逐元素复制数据。
接下来,下面一行代码须要特别注意:
a1[-2] = 20.2;
索引-2是什么意思呢?本章前面说过,这将被转换为以下代码:
*(a1-2) = 20.2;
其含义以下:找到a1指向的地方,向前移两个double元素,并将20.2存储到目的地。也就是说,将信息存储到数组的外面。与C语言同样,C++也不检查这种超界错误。在这个示例中,这个位置位于array对象a3中。其余编译器可能将20.2放在a4中,甚至作出更糟糕的选择。这代表数组的行为是不安全的。
vector和array对象可以禁止这种行为吗?若是您让它们禁止,它们就能禁止。也就是说,您仍可编写不安全的代码,以下所示:
a2[-2]=.5; a3[200] = 1.4
然而,您还有其余选择。一种选择是使用成员函数at()。就像可使用cin对象的成员函数getline()同样,您也可使用vector和array对象的成员函数at():
a2.at(1)=2.3;
中括号表示法和成员函数at()的差异在于,使用at()时,将在运行期间捕获非法索引,而程序默认将中断。这种额外检查的代价是运行时间更长,这就是C++让容许您使用任何一种表示法的缘由所在。另外,这些类还让您可以下降意外超界错误的几率。