目录
类模板std::vector
容器属性
函数总览:
Iterators(迭代器):
begin:将迭代器返回到开头。
end:将迭代器返回到结束。
rbegin:返回反向迭代器以反向开始。
rend:将反向迭代器返回到反向结束。
Capacity(容量):
max_size:迭返回代器可以作为内容保存的最大元素数。
size:返回向量中的元素数。
resize:改变容器大小
capacity[kə'pæsəti]:返回分配的存储容量大小
reserve:请求更改容量
empty:检测向量是否为空
Element access(元素访问):
operator[]:访问元素
at:访问元素
front:访问第一个元素
back:访问最后一个元素
Modifiers(编辑):
assign:分配向量内容
push_back:在最后添加元素
pop_back:删除最后元素
insert:插入元素
erase[ɪ'reɪz]:擦除元素
swap:交换元素
clear:清空元素
函数详解:
Iterators(迭代器):
begin: -->end: -->rbegin: -->rend:
Capacity(容量):
max_size: -->size: -->rsize: -->capacity: -->reserve: -->empty:
Element access(元素访问):
operator[]: -->at: -->front: -->back:
Modifiers(编辑):
assign: -->push_back: -->pop_back: -->insert: -->erase: -->swap: -->clear:
template > class vector; //通用模板
序列
序列容器中的元素按严格的线性顺序排序。各个元素按其顺序访问它们的位置。
动态数组
允许直接访问序列中的任何元素,甚至通过指针算术,并在序列的末尾提供相对快速的元素添加/删除。
分配感知器
容器使用allocator对象来动态处理其存储需求。
向量(vector)
向量是表示可以改变大小的数组的序列容器。
就像数组一样,向量使用连续的存储位置作为元素,这意味着它们的元素也可以使用常量指向其元素的偏移来访问,并且与数组一样有效。但与数组不同,它们的大小可以动态变化,其存储由容器自动处理。
在内部,向量使用动态分配的数组来存储它们的元素。可能需要重新分配此数组,以便在插入新元素时增大大小,这意味着分配新数组并将所有元素移动到该数组。就处理时间而言,这是相对昂贵的任务,因此,每次将元素添加到容器时,向量不会重新分配。
相反,向量容器可以分配一些额外的存储以适应可能的增长,因此容器可以具有大于包含其元素(即,其大小)严格需要的存储的实际容量。库可以实现不同的增长策略以在内存使用和重新分配之间取得平衡,但无论如何,重新分配只应以对数增长的大小间隔发生,以便在向量末尾插入单个元素可以提供摊销的常量时间复杂性(见push_back)。
因此,与数组相比,向量消耗更多内存以换取管理存储和以有效方式动态增长的能力。
与其他动态序列容器(dequse,lists和forward_lists)相比,向量非常有效地访问其元素(就像数组一样)并且相对有效地从其末尾添加或删除元素。对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其他位置差,并且与列表和forward_lists相比具有更少的一致的迭代器和引用。
member function:
注:迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。
begin:将迭代器返回到开头。
end:将迭代器返回到结束。
rbegin:返回反向迭代器以反向开始。
rend:将反向迭代器返回到反向结束。
max_size:迭返回代器可以作为内容保存的最大元素数。
size:返回向量中的元素数。
resize:改变容器大小
capacity[kə'pæsəti]:返回分配的存储容量大小
reserve:请求更改容量
empty:检测向量是否为空
operator[]:访问元素
at:访问元素
front:访问第一个元素
back:访问最后一个元素
assign:分配向量内容
push_back:在最后添加元素
pop_back:删除最后元素
insert:插入元素
erase[ɪ'reɪz]:擦除元素
swap:交换元素
clear:清空元素
将迭代器返回到开头。返回指向向量中第一个元素的迭代器。
iterator begin();
请注意,与成员vector :: front不同,它返回对第一个元素的引用,此函数返回指向它的随机访问迭代器。
/*======================================
函数操作:begin()
函数参数:无
函数返回:指向vector 中第一个元素iterator
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
for(int i = 1; i <= 5; i++)
myvector.push_back(i);
vector::iterator it; //it是迭代器指针类型,对vector 迭代器指针进行++,相当于对数组指针进行++操作。
std::cout << "myvector contains:";
for(it = myvector.begin(); it != myvector.end(); it++)
cout<<*it<<" ";
cout<
将迭代器返回到结束.返回一个迭代器,引用向量容器中的past-the-end元素(一个不存在的元素)。
iterator end();
后端元素是向量中最后一个元素后面的理论元素(此处可以理解为:向量中最后一个数据的下一个数据地址,如果这个位置曾经存储过数据,则*object.end()返回该数据的值)。它不指向任何元素,因此不应取消引用。因为标准库的函数使用的范围不包括其闭合迭代器指向的元素,所以此函数通常与vector :: begin结合使用以指定包含容器中所有元素的范围。 如果容器为空,则此函数返回与vector :: begin相同的值。
/*======================================
函数操作:end()
函数形参:无
函数返回:指向vector 中最后一个元素的下一个
元素的iterator
注意:[myvector.begin(), myvector.end())
表示左闭右开区间
======================================*/
#include
#include
int main()
{
std::vector myvector;
for(int i = 1; i <= 5; i++)
myvector.push_back(i);
std::cout << "myvector contains:";
for(std::vector::iterator it = myvector.begin(); it != myvector.end(); it++)
std::cout << *it << " ";
std::cout << std::endl;
return 0;
}
/*=======================================
函数输出:myvector contains:1 2 3 4 5
=======================================*/
注:迭代器不能等于 end();比如 it = myvector.end(); 运行结果如下图,end()是一个错误的指针
返回指向向量中最后一个元素的反向迭代器(即,它的反向开始)。
reverse_iterator rbegin();//reverse_iterator是双向迭代器类型。
反向迭代器向后迭代:增加它们将它们移向容器的开头。rbegin指向成员端指向的元素之前的元素。请注意,与成员vector :: back不同,它返回对此相同元素的引用,此函数返回反向随机访问迭代器。
/*======================================
函数操作:rbegin()
函数形参:无
函数返回:指向vector 中最后一个元素的iterator
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
for(int i = 1; i <= 5; i++)
myvector.push_back(i);
cout << "myvector contains:";
vector::reverse_iterator it;
for(it = myvector.rbegin(); it != myvector.rend(); it++)
cout << *it << " ";
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains:5 4 3 2 1
=======================================*/
将反向迭代器返回到反向结束。
reverse_iterator rbegin();
返回一个反向迭代器,指向向量中第一个元素之前的理论元素(被认为是它的反向结束)。vector::rbegin和vector::rend之间的范围包含了向量的所有元素(按相反的顺序)。
注:程序同上,此处省略
返回最大尺寸
size_type max_size() const;
返回向量可容纳的最大元素数。由于已知的系统或库实现限制,这是容器能够达到的最大可能大小,但是容器并不能保证能够达到这个大小:在达到这个大小之前,它仍然可能无法分配存储空间。
/*======================================
函数操作:max_size()
函数形参:无
函数返回:向量空间能存的最大元素数
======================================*/
#include
#include
using namespace std;
int main()
{
vector myints;
for(int i = 1; i <= 10; i++) myints.push_back(i);
cout << "size: " << myints.size() << endl;
cout << "capacity: " << myints.capacity() << endl;
cout << "max_size: " << myints.max_size() << endl; //因用户电脑情况而定,结果可能不同
return 0;
}
/*=======================================
函数输出:size: 10
capacity: 16
max_size: 4611686018427387903
=======================================*/
返回大小
size_type size() const;//成员类型size_type是无符号整数类型。
返回向量中的元素数。这是矢量中保存的实际对象的数量,不一定等于其存储容量。
/*======================================
函数操作:size()
函数形参:无
函数返回:向量中的元素数
======================================*/
#include
#include
using namespace std;
int main()
{
vector myints;
cout << "0.size: " << myints.size() << endl;
for(int i = 1; i <= 10; i++) myints.push_back(i);
cout << "1.size: " << myints.size() << endl;
myints.insert(myints.end(), 10, 100); //在结尾处插入10个 100
cout << "3.size: " << myints.size() << endl;
myints.pop_back();
cout << "4.size: " << myints.size() << endl;
return 0;
}
/*=======================================
函数输出:0.size: 0
1.size: 10
3.size: 20
4.size: 19
=======================================*/
改变大小-对应于 size()
void resize (size_type n, value_type val = value_type());
调整容器大小以使其包含n个元素。如果n小于当前容器大小,则内容将减少为前n个元素,删除超出(并销毁它们)的元素。如果n大于当前容器大小,则通过在末尾插入尽可能多的元素来扩展内容以达到n的大小。如果指定了val,则新元素将初始化为val的副本,否则,它们将进行值初始化。如果n也大于当前容器容量,自动重新分配分配的存储空间。请注意,此函数通过插入或删除容器中的元素来更改容器的实际内容。
/*======================================
函数操作:size()
函数形参:(1)指定大小 n(无符号整型)
(2)当 n 大于当前容器,将指定内容复制到
添加元素的对象。
函数返回:无
======================================*/
#include
#include
using namespace std;
int main()
{
vector myints;
for(int i = 1; i <= 10; i++) myints.push_back(i);
cout << "size: " << myints.size() << endl;
myints.resize(5); //删除并销毁位数 5 之后的数据
cout << "size: " << myints.size() << endl;
myints.resize(8, 21); //在原向量尾以元素 21 扩展到 8 位大小。
cout << "size: " << myints.size() << endl;
myints.resize(12); //在原向量尾以元素 0 扩展到指定为数 12 。
for(int i = 0; i < myints.size(); i++)
cout << myints[i] << " ";
cout<
返回分配的存储容量大小
size_type capacity() const;
返回当前分配给向量的存储空间的大小,用元素表示。这个容量不一定等于向量的大小。它可以是相等的或更大的,有额外的空间允许容纳增长,而不需要在每次插入时重新分配。注意,这个容量并不假设向量的大小受到限制。当这个容量耗尽并且需要更多容量时,容器会自动扩展它(重新分配它的存储空间)。向量大小的理论极限由成员max_size给出。向量的容量可以通过调用成员vector::reserve显式地更改。
/*======================================
函数操作:size()
函数形参:(1)指定大小 n(无符号整型)
(2)当 n 大于当前容器,将指定内容复制到
添加元素的对象。
函数返回:无符号整型
======================================*/
#include
#include
using namespace std;
int main()
{
vector myints;
myints.resize(1);
cout << "size: " << myints.size() << endl;
cout << "capacity: " << myints.capacity() << endl;
myints.resize(4);
cout << "size: " << myints.size() << endl;
cout << "capacity: " << myints.capacity() << endl;
myints.resize(6);
cout << "size: " << myints.size() << endl;
cout << "capacity: " << myints.capacity() << endl;
myints.resize(10);
cout << "size: " << myints.size() << endl;
cout << "capacity: " << myints.capacity() << endl;
for(int i = 0; i < myints.size(); i++)
myints[i] = i;
for(int i = 0; i < myints.capacity(); i++)
cout << myints[i] << " ";
cout << endl;
return 0;
}
/*=======================================
函数输出:size: 1
capacity: 1
size: 4
capacity: 4
size: 6
capacity: 8
size: 10
capacity: 16
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0
=======================================*/
请求更改容量-对应于 capacity()
void reserve (size_type n);
请求向量容量至少足以包含n个元素。如果n大于当前向量容量,则该函数使容器重新分配其存储,将其容量增加到n(或更大)。在所有其他情况下,函数调用不会导致重新分配,并且矢量容量不会受到影响。此函数对向量大小没有影响,不能改变其元素。
/*======================================
函数操作:reserve()
函数形参:无
函数返回:无
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
vector::size_type sz;
sz = myvector.capacity();
std::cout << "making foo grow: " << endl;
for(int i = 0; i < 100; i++)
{
myvector.push_back(i);
if(sz != myvector.capacity())
{
sz = myvector.capacity();
cout << "capacity changed: " << sz << endl;
}
}
std::vector bar;
sz = bar.capacity();
bar.reserve(100); //相当于 C 语言中的 malloc,C++ 中的 new,自己开辟一块固定大小的内存空间
std::cout << "making bar grow:\n";
for (int i=0; i<100; ++i) {
bar.push_back(i);
if (sz!=bar.capacity()) {
sz = bar.capacity();
std::cout << "capacity changed: " << sz << '\n';
}
}
return 0;
}
/*=======================================
函数输出:making foo grow:
capacity changed: 1
capacity changed: 2
capacity changed: 4
capacity changed: 8
capacity changed: 16
capacity changed: 32
capacity changed: 64
capacity changed: 128
making bar grow:
capacity changed: 100
=======================================*/
测试向量是否为空
bool empty() const;
返回向量是否为空(即其大小是否为0)。此功能不会以任何方式修改容器。要清除向量的内容,请参阅vector :: clear。
/*======================================
函数操作:empty()
函数形参:无
函数返回:bool 0-非空;1-空
======================================*/
#include
#include
using namespace std;
int main()
{
vector myints;
int sum = 0;
for(int i = 1; i <= 10; i++)
myints.push_back(i);
while(!myints.empty())
{
sum += myints.back();
myints.pop_back();
}
cout << "total: " << sum << endl;
return 0;
}
/*=======================================
函数输出:total: 55
=======================================*/
返回对向量容器中位置为n的元素的引用。
reference operator[] (size_type n);//成员类型reference和const_reference是容器元素的引用类型
类似的成员函数vector::at与这个操作符函数具有相同的行为,但vector::at是有界检查的,如果请求的位置超出范围,则通过抛出out_of_range异常发出信号。可移植程序不应该使用超出范围的参数n调用此函数,因为这会导致未定义的行为。
注:程序历程见 capacity
访问元素
reference at (size_type n);
返回对向量中位置n处元素的引用。 该函数自动检查n是否在向量中的有效元素的范围内,如果不是,则抛出out_of_range异常(即,如果n大于或等于其大小)。这与成员运算符[]形成对比,后者不检查边界。
/*======================================
函数操作:at()
函数形参:元素在容器中的位置
函数返回:该位置元素值
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector(10); //初始化为 10 个 0
for(int i = 0; i < myvector.size(); i++)
myvector.at(i) = i;
cout << "myvector contains:";
for(int i = 0; i < myvector.size(); i++)
cout << " " << myvector.at(i);
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 0 1 2 3 4 5 6 7 8 9
=======================================*/
访问第一个元素
reference front();
返回对向量中第一个元素的引用。与成员vector :: begin不同,它返回一个迭代器到同一个元素,这个函数返回一个直接引用。在空容器上调用此函数会导致未定义的行为。
/*======================================
函数操作:front()
函数形参:无
函数返回:向量容器中第一个元素的引用
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
myvector.push_back(78);
myvector.push_back(16);
myvector.front() -= myvector.back();
cout << "myvector.front() = " << myvector.front() << endl;
return 0;
}
/*=======================================
函数输出:myvector.front() = 62
=======================================*/
访问最后一个元素
reference back();
返回对向量中最后一个元素的引用。与成员vector :: end不同,它返回一个直接通过此元素的迭代器,此函数返回一个直接引用。在空容器上调用此函数会导致未定义的行为。
分配向量内容
range (1) | |
---|---|
fill (2) | |
将新内容分配给向量,替换其当前内容(相当于清空),并相应地修改其大小。
/*======================================
函数操作:assign()
函数形参:和创建vector 相同的三种输入形式
函数返回:无-void
======================================*/
#include
#include
using namespace std;
int main()
{
vector first;
vector secend;
vector third;
first.assign(7, 100);
vector::iterator it;
it = first.begin() + 1;
secend.assign(it, first.end() - 1);
int myints[] = {1996, 4, 5};
third.assign(myints, myints + 3);
cout << "Size of fist: " << first.size() << endl;
cout << "Size of secend: " << secend.size() << endl;
cout << "Size of third: " << third.size() << endl;
return 0;
}
/*=======================================
函数输出:Size of fist: 7
Size of secend: 5
Size of third: 3
=======================================*/
末尾添加元素
void push_back (const value_type& val);//成员类型value_type是容器中元素的类型,在向量中定义为其第一个模板参数(T)的别名。
在向量的末尾添加一个新元素,在其当前的最后一个元素之后。val的内容被复制(或移动)到新元素。这有效地将容器大小增加一,如果 - 并且仅当新的矢量大小超过当前矢量容量时,这导致分配的存储空间的自动重新分配。
注:见之前程序
删除最后一个元素
void pop_back();
移除向量中的最后一个元素,有效地将容器大小减少一个。这会破坏已删除的元素。
注:见 empty();
通过在指定位置的元素之前插入新元素来扩展向量,从而通过插入的元素数量有效地增加容器大小。
single element (1) | |
---|---|
fill (2) | |
range (3) | |
当且仅当新向量大小超过当前向量容量时,将自动重新分配分配的存储空间。因为向量使用数组作为它们的底层存储,所以将元素插入到向量末端以外的位置会导致容器将位置之后的所有元素重新定位到它们的新位置。与其他类型的序列容器(如list或forward_list)对相同操作执行的操作相比,这通常是一个低效的操作。这些参数决定了插入了多少元素,并将它们初始化为哪些值。
返回第一个新插入元素的迭代器。
/*======================================
函数操作:insert()
函数形参:(1)插入位置,插入值
(2)插入位置,插入数量,插入值
(3)插入位置,另一vector插入起点的 iterator,插入终点iterator
(4)插入位置,数组插入起点指针,数组插入终点指针
函数返回:插入元素的第一个元素的 iterator
======================================*/
#include
#include
using namespace std;
int main()
{
vector first(3, 100);
vector::iterator it;
it = first.begin();
it = first.insert(it, 200);
first.insert(it, 2, 300);
it = first.begin();
vector secend(2, 400);
first.insert(it + 2, secend.begin(), secend.end());
int myarray[] = {501, 502, 503};
first.insert(first.begin(), myarray, myarray + 3);
cout << "myvector contains: ";
for(it = first.begin(); it < first.end(); it++)
cout << *it << " ";
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 501 502 503 300 300 400 400 200 100 100 100
=======================================*/
从向量中移除单个元素(位置)或一系列元素([first,last))。
iterator erase (iterator position);
iterator erase (iterator first, iterator last);
这有效地减少了容器的大小,删除了被删除的元素数量。
/*======================================
函数操作:erase()
函数形参:(1)删除位置
(2)删除起点iterator,删除终点iterator
函数返回:iterator,指向调用删除的最后一个额元素后面元素的新位置
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
// set some values(from 1 to 10)
for(int i = 1; i <= 10; i++)
myvector.push_back(i);
//erase the 6th element
myvector.erase(myvector.begin() + 5);
//erase the first 3 elements
myvector.erase(myvector.begin(), myvector.begin() + 3);
cout << "myvector contains: ";
for(unsigned i = 0; i < myvector.size(); i++)
cout << myvector[i] << " ";
cout << endl;
return 0;
}
/*=======================================
函数输出:myvector contains: 4 5 7 8 9 10
=======================================*/
交换内容
void swap (vector& x);
通过x的内容交换容器的内容,x是另一个相同类型的矢量对象。尺寸可能不同。在调用此成员函数之后,此容器中的元素是在调用之前在x中的元素,而x的元素是在此中的元素。所有迭代器,引用和指针对交换的对象仍然有效。请注意,存在一个非成员函数,其名称相同,交换,重载该算法,其优化行为与此成员函数类似。
/*======================================
函数操作:swap()
函数形参:要交换的 vector 对象
函数返回:无 - void
======================================*/
#include
#include
using namespace std;
int main()
{
vector foo(3, 100);
vector bar(5, 200);
foo.swap(bar);
cout << "foo contains: ";
for(vector::iterator it = foo.begin(); it < foo.end(); it++)
cout << *it << " ";
cout << endl;
cout << "bar contains: ";
for(unsigned i = 0; i < bar.size(); i++)
cout << bar.at(i) << " ";
cout << endl;
return 0;
}
/*=======================================
函数输出:foo contains: 200 200 200 200 200
bar contains: 100 100 100
=======================================*/
从向量中删除所有元素(被销毁),使容器的大小为0。
void clear();
不能保证重新分配,并且由于调用此函数,不能保证向量容量发生变化。强制重新分配的典型替代方法是使用swap:
/*======================================
函数操作:swap()
函数形参:要交换的 vector 对象
函数返回:无 - void
======================================*/
#include
#include
using namespace std;
int main()
{
vector myvector;
myvector.push_back (100);
myvector.push_back (200);
myvector.push_back (300);
cout << "myvector contains:";
for (unsigned i=0; i