模板类vector 、array 是数组的替代品。
- vector
模板类vector类似于string类,是一种动态数组。 基本上,它是使用new创建动态数组的替代品。 实际上,vector类确实使用new和delete来管理内存,只是这种工作是自动完成的。
vector是序列容器,表示可以改变大小的数组。 与数组一样,vector使用连续的存储位置存储其元素,这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素,其效率与数组中的相同。但与数组不同,它们的大小可以动态变化,其存储由容器自动处理。
效率: vector类功能比较强大,但付出的代价是效率稍低。如果需要的是长度固定的数组,使用数组是更佳的选择,但代价是不那么方便和安全。
创建一个名为vt的vector对象,它可存储n_elem个类型为typeName的元素: vector<typeName> vt(n_elem);
#include <iostream>
#include <vector>
int main() {
std::vector<int> myvector;
int myint;
std::cout << "Please enter some integers (enter 0 to end):\n";
do {
std::cin >> myint;
myvector.push_back(myint);
} while (myint);
std::cout << "myvector stores " << myvector.size() << " numbers.\n";
return 0;
}
Please enter some integers (enter 0 to end):
|1 2 3<Enter>
|4 5<Enter>
|60<Enter>
|0<Enter>
myvector stores 7 numbers.
- array(C++11)
效率: 鉴于vector的效率问题,C++11新增了模板类array。与数组一样,array对象的长度也是固定的,也使用栈(静态内存分配),而不是自由存储区,因此其效率与数组相同,但更方便,更安全。
array是固定大小的序列容器:它们包含按严格线性序列排序的特定数量的元素。 在内部,array除了包含的元素外,不保留任何数据(甚至不保留其大小,这是一个模板参数,在编译时固定)。就存储大小而言,它与使用该语言的括号语法([])声明的普通数组一样高效。这个类只向其添加了一层成员和全局函数,因此数组可以用作标准容器。
创建一个名为arr的array对象,它包含n_elem个类型为typeName的元素: array<typeName, n_elem> arr;
示例:
#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;
return 0;
}
a1[2]:3.6 at 0x128e9ffb70
a2[2]:0.142857 at 0x14f3eac1b90
a3[2]:1.62 at 0x128e9ffb30
a4[2]:1.62 at 0x128e9ffb10
首先,注意到无论是数组、vector对象还是array对象,都可使用标准数组表示法来访问各个元素。 其次,从地址可知,array对象和数组存储在相同的内存区域(即栈)中,而vector对象存储在另一个区域(自由存储区或堆)中。 第三,注意到可以将一个array对象赋给另一个array对象;而对于数组,必须逐元素复制数据。
不端行为: 如果示例代码中有:a1[-2] = 20.2; 是被程序允许的,只是不同编译器作出的结果不一样,甚至做出更糟糕的结果,这表明数组的行为是不安全的。a2[-2] = .5; a3[200] = 1.4; 也都是程序允许的。与C语言一样,C++也不检查这种超界错误。
然而,你还有其他选择,可以这样:a2.at(1) = 2.3; 。中括号表示法和成员函数at() 的差别在于,使用at()时,将在运行期间捕获非法索引,而程序默认将中断。这种额外检查的代价是运行时间更长,这就是C++允许你使用任何一种表示法的原因所在。 另外,这些类还让你能够降低意外超界错误的概率。例如,它们包含成员函数begin()和end(),让你能够确定边界,以免无意间超界。
|