之前看了一遍容器和迭代器,但听了学长说的,感觉我的理解有点偏差。打算来学习学习容器的具体用法,敲一敲。
先来学习顺序容器vector的用法。
类似于C风格的数组;元素内存空间连续,每个元素有自己的槽。在vector中可建立索引。可以在任何位置添加或删除新元素,需要线性时间。在尾部执行操作时,实际运行时间为摊还常量。(那么什么是摊还常量呢?)。随机访问单个元素的复杂度为常量时间。
在vector头文件中被定义为一个带有2个类型参数的类模板:一个参数为要保存的元素类型,另一个参数为分配器(allocator)类型。
template <class T, class Allocator = allocator<T>> class vector;
Allocator参数指定内存分配器对象的类型,客户可设置内存分配器。(这章介绍的都是默认模板参数的内存分配器)
vector最简单的用法莫过于把它当做C风格数组的替代品(长度固定)。vector提供了一个可以指定元素数量的构造函数,还提供了重载的operator[]来访问和修改元素。
同时C++标准指出,通过operator[]来访问vector边界之外的元素,是UB。
除了使用operator[]运算符之外,还能用at(),front(),back()访问元素。
at() = operator[],不过at()会检查边界,并在越界时抛出out_of_range。
front()和back()分别返回第一个元素和最后一个元素的引用。
下面敲一个来“标准化”考试分数的程序,经过标准化后,最高分100,其他所有分数据此调整。它创建了一个带有10个double值的vector,然后读入10个值,将每个值除以最高分,再乘以100,最后打印出新值。
vector<double> doubleVector(10);
double max = -numeric_limits<double>::infinity();
for(size_t i =0; i < doubleVector.size();i++){
cout << "Enter score " << i+1 << ": ";
cin >> doubleVector[i];
if(doubleVector[i]>max){
max = doubleVector[i];
}
}
max /= 100.0;
for(auto& element: doubleVector){
element /= max;
cout << element << " ";
}
这里要注意的几点是:(1).第一个for循环使用size()方法来确定容器元素的个数。
(2).基于区间的for循环中用auto&而不是auto,因为这里要用引用,才能在每次迭代中修改元素。
vector真正好用之处在于它的动态增长。如前面的处理分数程序,如果要再加上一项任意数量的要求,那么则有:
vector<double> doubleVector;
double max = -numeric_limits<double>::infinity();
for(size_t i = 1; true; i++){
double temp;
cout << "Enter score " << i << "(-1 to stop)";
cin >> temp;
if(temp == -1) break;
doubleVector.push_back(temp);
if(temp > max) max = temp;
}
max /= 100.0;
for(auto& element: doubleVector){
element/= max;
cout << element << " ";
}
这创建了一个不包含元素的空vector,然后每读取一个值,通过push_back()方法添加到vector,push_back()能为新元素分配空间。基于区间的for循环不需要做修改。
默认的构造函数的创建一个不包含元素的vector
vector<int> intVector;
但也可以指定元素个数,并指定元素的值,如:vector<int> intVector(10,100)
这个便指定了10个元素,初始化值为100
如果没有提供默认值,则对新对象进行0初始化。0初始化通过默认构造函数创建对象,将基本的整数类型初始化为0,浮点数0.0,指针类型nullptr。
还可以创建内建类的vector,如下所示:vector<string> stringVector(10,"Hello");
用户自定义的类也可:
class Element{
public:
Element(){}
virtual ~Element() = default;
};
...
vector<Element> elementVector;
还可以用初始化列表:vector<int> intVector({1,2,3,4,5,6});
。
initializer_list还可以用于统一初始化:
vector<int> intVector1 = {1,2,3,4,5,6};
vector<int> intVector2{1,2,3,4,5,6};
还可以在堆上分配:auto elementVector = make_unique<vector<Element>>(10);
原文:https://www.cnblogs.com/ranbom/p/12845213.html