C++——模板类vector和array

来源:互联网 发布:出售淘宝买家信息 编辑:程序博客网 时间:2024/05/16 11:32

数组的替代品——模板类vector和array

模板类vector和array是数组的替代品。

1. 模板类vector

模板类vetor类似于string类,也是一种动态数组。可以在运行阶段设置vector对象的长度,可在末尾附加新数据,还可在中间插入新数据。基本上,它是使用new创建动态数组的替代品。实际上,vector类确实使用new和delete来管理内存,但这种工作是自动完成的。

首先,要使用vector对象,必须包含头文件vector。其次,vector包含在名称空间std中,因此您可使用using编译指令,using声明或者std::vector。第三,模板使用不同的语法来指出它存储的数据类型。第四,vector类使用不同的语法来制定元素数。下面示例:

#include<vector>...using namespace std;vector<int> vi; // 创建一个长度为0的int数组int n;cin >> n;vector<double> vd(n);//创建一个长度为n doubles的数组

由于vector对象在插入或添加值时自动调整长度,因此可以将vi的初始长度设置为零。如果要调整长度,需要使用vector包中的各种方法。
一般的,下面的生命创建一个名为vt的vector对象,可以存储n_elem个类型为typeName的元素:

vector<typeName> vt(n_elem); // 参数n_elem可以使整型常量,也可以是整型变量

2. 模板类array(C++11)

vector类的功能比数组强大,但付出的代价是效率稍低。如果需要的是长度固定的数组,使用数组是更佳的选择,但代价是不那么方便和安全。因此,C++11增加了模板类array,它也位于名称空间std中。与数组一样,array对象的长度也是固定的,也使用栈(静态内存分配),而不是自由存储区,因此其效率与数组相同,但更方便,更安全。要创建array对象,需要包含头文件array。array对象的创建语法与vector稍有不同:

#include<array>...using namespace std;array<int,5> ai; //创建一个5个int的数组array<double,4> ad = {1.2,2.1,3.42,4.3};

推而广之,下面的声明创建一个名为arr的array对象,它包含n_elem个类型为typeName的元素:

array<typeName,n_elem> arr; //与vector对象不同,n_elem不能是变量

在C++11中,可将列表初始化用于vector和array对象,但在C++98中,不能对vector对象这样做。

3. 比较数组、vector对象和array对象

要了解三者的区别,看一个程序示例。

#include<iostream>#include<vector>#include<array>int main(){    using namespace std;    double a1[4] = {1.2,2.4,3.6,4.8};     vector<double> a2(4);    a2[0] = 1.0 / 3.0;    a2[1] = 1.0 / 5.0;    a2[2] = 1.0 / 7.0;    a2[3] = 1.0 / 9.0;    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;}
下面是该程序的输出结果:a1[2]: 3.6 at 0x28ccce8a2[2]: 0.142857 at 0xca0328a3[2]: 1.62 at 0x28ccc8a4[2]: 1.62 at 0x28cca8a1[-2]: 20.2 at 0x28ccc8a3[2]: 20.2 at 0x28ccc8a4[2]: 1.62 at 0x28ccc8

首先,无论是数组、vector对象还是array对象,都可使用标准数组表示法来访问各个元素。其次,从地址可知,array对象和数组存储在相同的内存区域(即栈)中,而vector对象存储在另一个区域(自由存储区或堆)中。第三,注意到可以将一个array对象赋值给另一个array对象;而对于数组,必须逐个元素复制数据。
对于这一行代码

a1[-2] = 20.2;

索引-2的含义是:找到a1指向的地方,向前移动两个double元素,并将20.2存储得到目的地。也就是说,将信息存储到数组的外面。与C语言一样,C++不检查这种超界错误。在这个示例中,这个位置位于array对象a3中。其他编译器可能将20.2放在a4中,或者其他的可能性。这表明数组的行为是不安全的。
vector与array对象仍允许这种不安全的代码。
但可以使用其他选择。一种选择是使用成员函数at().就想可以使用cin对象的成员函数getline()一样。

a2.at(1) = 2.3 //将2.3赋值给a2[1]

中括号表示法和成员函数at()的差别在于,使用at()时,将在运行期间捕获非法索引,而程序默认将中断。这种额外检查的代价就是运行时间更长。另外,这些类包含成员函数begin()和end(),能够确定边界,一面无意间超界。

原创粉丝点击