一、前言

vector和array的不同之处在于:array 实现的是动态数组(容量固定的数组),而 vector 实现的是一个动静数组。
vector 容器以类模板 vector<T>( T 示意存储元素的类型)的模式定义在 <vector> 头文件中,并位于 std 命名空间中。因而,在创立该容器之前,代码中需蕴含如下内容:

#include <vector>using namespace std;

阐明:std命名空间也可在应用vector容器时额定注明,如:

std::vector<double> values;

二、创立vector的形式

①std::vector<int> vecInt;②std::vector<int> vecInt {1,5,23,45,87};③std::vector<int> vecInt(10);④std::vector<int> vecInt(10, 4);

①形式创立一个空的vector容器,因为容器中没有元素,所以没有调配空间,当用户增加元素时,vector会主动分配内存空间。如果创立好的vector容器的容量有余,可通过reserve()减少容器的容量。须要留神的是:

调用 reserve() 不会影响已存储的元素,也不会生成任何元素,即 vecInt 容器内此时依然没有任何元素;如果调用 reserve() 来减少容器容量,之前创立好的任何迭代器(例如开始迭代器和完结迭代器)都可能会生效,因为为了减少容器的容量,vector<T> **容器的元素可能曾经被复制或移到了新的内存地址**。

②形式创立一个蕴含有5个元素的vector容器
③形式创立一个有10个元素、默认初始值为0的vector容器
④形式创立一个有10个元素、指定初始值为4的vector容器
圆括号 () 和大括号 {} 是有区别的,前者示意元素的个数,而后者则示意 vector 容器中的元素值。

三、成员函数

成员函数性能
begin()返回指向容器中第一个元素的迭代器
end()返回指向容器最初一个元素所在位置后一个地位的迭代器,通常和 begin() 联合应用
rbegin()返回指向最初一个元素的迭代器
rend()返回指向第一个元素所在位置前一个地位的迭代器
cbegin()和 begin() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改元素
cend()和 end() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改元素
crbegin()和 rbegin() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改元素
crend()和 rend() 性能雷同,只不过在其根底上,减少了 const 属性,不能用于批改元素
size()返回理论元素个数
max_size()返回元素个数的最大值,个别是 232-1,所以咱们很少会用到这个函数
resize()扭转理论元素的个数
capacity()返回以后容量
empty()判断容器中是否有元素,若无元素,则返回 true;反之,返回 false
reserve()减少容器的容量
shrink _to_fit()将内存缩小到等于以后元素理论所应用的大小
operator[ ]重载了 [ ] 运算符,能够向拜访数组中元素那样,通过下标即可拜访甚至批改 vector 容器中的元素
at()应用通过边界查看的索引拜访元素
front()返回第一个元素的援用
back()返回最初一个元素的援用
data()返回指向容器中第一个元素的指针
assign()用新元素替换原有内容
push_back()在序列的尾部增加一个元素
pop_back()移出序列尾部的元素
insert()在指定的地位插入一个或多个元素
erase()移出一个元素或一段元素
clear()clear()
swap()替换两个容器的所有元素
emplace()在指定的地位间接生成一个元素
emplace_back()在序列尾部生成一个元素
std::swap(x , y)非成员函数,替换数据

四、迭代器的用法

vector的迭代器成员函数和array根本是一样的,如下:
begin()
end()
rbegin()
rend()
cbegin()
cend()
crbegin()
crend()
具体性能图示与https://segmentfault.com/a/11...

1、vector迭代器的独特之处

vector 容器能够随着存储元素的减少,自行申请更多的存储空间。因而,在创立 vector 对象时,咱们能够间接创立一个空的 vector 容器,并不会影响后续应用该容器。
vector 容器在申请更多内存后,再次应用之前的迭代器,可能会导致解体,因为vector容器在减少容量之后,首个元素的存储地址产生了变动,这个时候再应用之前创立的迭代器显然是谬误的,这个时候须要从新初始化迭代器。

五、拜访vector容器元素的形式

1、下标形式[]

相似C++中数组的拜访形式,vector容器的索引是从0开始的,和数组一样。须要保障下标 n 的值不会超过容器的容量,否则会产生拜访越界的谬误。

2、at()

当传给at()的索引值越界时,会抛出异样

3、遍历vector容器元素

依据size()获取vector容器的大小,遍历容器中的元素即可
留神:不能应用 capacity() ,因为它返回的是 vector 容器的容量而不是理论存储元素的个数

六、vector容器增加元素

向 vector 容器中增加元素的惟一形式就是应用它的成员函数

1、push_back()

在 vector 容器尾部增加一个元素

2、emplace_back()

C++11新增的,性能和push_back()雷同。
既然性能雷同,为什么要减少一个emplace_back()呢?

首先咱们理解一下emplace_back() 和 push_back() 的区别:底层实现的机制不同。push_back() 向容器尾部增加元素时,首先会创立这个元素,而后再将这个元素拷贝或者挪动到容器中(如果是拷贝的话,预先会自行销毁先前创立的这个元素);而 emplace_back() 在实现时,则是间接在容器尾部创立这个元素,省去了拷贝或挪动元素的过程,因而emplace_back()的执行效率比push_back()高。

七、vector插入元素

1、insert()

在 vector 容器的指定地位插入一个或多个元素。该函数的语法格局有多种,如下:

格局阐明
iterator insert(pos,elem)在迭代器 pos 指定的地位之前插入一个新元素elem,并返回示意新插入元素地位的迭代器
iterator insert(pos,n,elem)在迭代器 pos 指定的地位之前插入 n 个元素 elem,并返回示意第一个新插入元素地位的迭代器
iterator insert(pos,first,last)在迭代器 pos 指定的地位之前,插入其余容器(不仅限于vector)中位于 [first,last) 区域的所有元素,并返回示意第一个新插入元素地位的迭代器
iterator insert(pos,initlist)在迭代器 pos 指定的地位之前,插入初始化列表(用大括号{}括起来的多个元素,两头有逗号隔开)中所有的元素,并返回示意第一个新插入元素地位的迭代器

2、emplace()

C++ 11中新增的成员函数,用于在 vector 容器指定地位之前插入一个新的元素。

iterator emplace (const_iterator pos, args...);

pos 为指定插入地位的迭代器;args... 示意与新插入元素的构造函数绝对应的多个参数;该函数会返回示意新插入元素地位的迭代器。
留神:
①当拷贝构造函数和挪动构造函数同时存在时,insert() 会优先调用挪动构造函数。
②理论中,emplace() 的运行效率比insert()高。emplace() 在插入元素时,是在容器的指定地位间接结构元素,而不是先独自生成,再将其复制(或挪动)到容器中。

八、 vector删除元素的几种形式

如下:

函数性能
pop_back()删除 vector 容器中最初一个元素,该容器的大小(size)会减 1,但容量(capacity)不会产生扭转
erase(pos)删除 vector 容器中 pos 迭代器指定地位处的元素,并返回指向被删除元素下一个地位元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会产生扭转
swap(beg)、pop_back()先调用 swap() 函数替换要删除的指标元素和容器最初一个元素的地位,而后应用 pop_back() 删除该指标元素
erase(beg,end)删除 vector 容器中位于迭代器 [beg,end)指定区域内的所有元素,并返回指向被删除区域下一个地位元素的迭代器。该容器的大小(size)会减小,但容量(capacity)不会产生扭转
remove()删除容器中所有和指定元素值相等的元素,并返回指向最初一个元素下一个地位的迭代器。值得一提的是,调用该函数不会扭转容器的大小和容量
clear()删除 vector 容器中所有的元素,使其变成空的 vector 容器。该函数会扭转 vector 的大小(变为 0),但不是扭转其容量

九、实例

1、拜访vector容器中的元素

#include <iostream>#include <vector>using namespace std;int main(){    //初始化vector    std::vector<int> vecInt;    std::vector<int> vecInt2{ 3,8,9,6,7,10 };    std::vector<int> vecInt3(10);    std::vector<int> vecInt4(20, 4);       for (size_t i = 0; i < vecInt.size(); i++)    {        std::cout << "vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "vecInt size: " << vecInt.size() << " capacity: " << vecInt.capacity() << std::endl;    for (size_t i = 0; i < vecInt2.size(); i++)    {        std::cout << "vecInt2[" << i << "]=" << vecInt2[i] << std::endl;    }    std::cout << "vecInt2 size: " << vecInt2.size() << " capacity: " << vecInt2.capacity() << std::endl;    for (size_t i = 0; i < vecInt3.size(); i++)    {        std::cout << "vecInt3[" << i << "]=" << vecInt3[i] << std::endl;    }    std::cout << "vecInt3 size: " << vecInt3.size() << " capacity: " << vecInt3.capacity() << std::endl;    for (size_t i = 0; i < vecInt4.size(); i++)    {        std::cout << "vecInt4[" << i << "]=" << vecInt4[i] << std::endl;    }    std::cout << "vecInt4 size: " << vecInt4.size() << " capacity: " << vecInt4.capacity() << std::endl;    system("pause");    return 0;}

后果如下:

2、vector容器迭代器的应用

 //初始化vector    std::vector<int> vecInt{ 3,8,9,6,7,10,34,57,981,301 };    //begin、end    int i = 0;    std::vector<int>::iterator vecIter = vecInt.begin();    for (; vecIter != vecInt.end(); vecIter++)    {        std::cout << "begin and end test: vecInt[" << i++ << "]=" << *vecIter << std::endl;    }    //rbegin、rend    i = 0;    std::vector<int>::reverse_iterator vecIterR = vecInt.rbegin();    for (; vecIterR != vecInt.rend(); vecIterR++)    {        std::cout << "rbegin and rend test: vecInt[" << i++ << "]=" << *vecIterR << std::endl;    }    //cbegin、cend     i = 0;    std::vector<int>::const_iterator vecIterC = vecInt.cbegin();    for (; vecIterC != vecInt.cend(); vecIterC++)    {        std::cout << "cbegin and cend test: vecInt[" << i++ << "]=" << *vecIterC << std::endl;    }    //crbegin、crend    i = 0;    std::vector<int>::const_reverse_iterator vecIterCR = vecInt.crbegin();    for (; vecIterCR != vecInt.crend(); vecIterCR++)    {        std::cout << "crbegin and crend test: vecInt[" << i++ << "]=" << *vecIterCR << std::endl;    }

后果如下:

3、拜访vector容器元素

 //初始化vector    std::vector<int> vecInt{ 3,8,9,6,7,10,34,57,981,301 };    //下标形式    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    //at()形式    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "vecInt[" << i << "]=" << vecInt.at(i) << std::endl;    }    //迭代器形式    int i = 0;    std::vector<int>::iterator vecIter = vecInt.begin();    for (; vecIter < vecInt.end(); vecIter++)    {        std::cout << " iterator vecInt[" << i++ << "]=" << *vecIter << std::endl;    }

后果如下:

4、往vector中插入元素

//初始化vector    std::vector<int> vecInt{ 3,8,9,6,7,10,34,57,981,301 };    //增加元素    vecInt.push_back(4301);    vecInt.emplace_back(910);    //下标形式    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "push_back and emplace_back vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    //insert    vecInt.insert(vecInt.begin(), 72);    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "insert begin vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    vecInt.insert(vecInt.end(), 189);    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "insert end vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::array<int, 2> arrayInt{ 13,15 };    vecInt.insert(vecInt.end(), arrayInt.begin(), arrayInt.end());    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "insert array vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    vecInt.insert(vecInt.end(), { 73,98,49 });    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "insert array2 vecInt[" << i << "]=" << vecInt[i] << std::endl;    }

后果如下:

5、删除vector容器中的元素

  //初始化vector    std::vector<int> vecInt{ 3,8,9,6,7,10,34,57,981,301,201,701,623,82,201,2909 };    vecInt.pop_back();    //    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "pop_back vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "pop_back vecInt size: " << vecInt.size() << "capacity is :" << vecInt.capacity() << std::endl;    //erase    vecInt.erase(vecInt.begin() + 3);    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "erase vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "erase vecInt size: " << vecInt.size() << "capacity is :" << vecInt.capacity() << std::endl;    //swap    swap(*(std::begin(vecInt) + 1), *(std::end(vecInt) - 1));    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "after swap vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "after swap vecInt size: " << vecInt.size() << "capacity is :" << vecInt.capacity() << std::endl;    vecInt.pop_back();        for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "after swap rest vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    //erase指定范畴    vecInt.erase(vecInt.begin() + 2, vecInt.end() - 5);    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "erase appoint vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    //remove    std::remove(vecInt.begin(), vecInt.end(), 3);    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "after remove vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "remove vecInt size: " << vecInt.size() << "capacity is :" << vecInt.capacity() << std::endl;    //clear    vecInt.clear();    for (int i = 0; i < vecInt.size(); i++)    {        std::cout << "clear vecInt[" << i << "]=" << vecInt[i] << std::endl;    }    std::cout << "clear vecInt size: " << vecInt.size() << "capacity is :" << vecInt.capacity() << std::endl;

后果如下:


阐明:
pop_back:执行后删除了最初一个元素,容器大小-1,容量不变;
erase:执行后,会返回一个指向删除元素所在位置下一个地位的迭代器,erase在删除元素时,会将删除地位后续的元素陆续前移,并将容器的大小减-1;erase也能够删除指定区域的元素,会返回指向此区域之后一个地位的迭代器;
remove:删除容器中和指定元素值雷同的所有元素,在对容器执行完 remove() 函数之后,因为该函数并没有扭转容器原来的大小和容量,因而借助 remove() 返回的迭代器实现正确的遍历
remove()的实现原理是:在遍历容器中的元素时,一旦遇到指标元素,就做上标记,而后持续遍历,直到找到一个非指标元素,即用此元素将最先做标记的地位笼罩掉,同时将此非指标元素所在的地位也做上标记,期待找到新的非指标元素将其笼罩。通过 remove() 函数删除掉 demo 容器中的多个指定元素,该容器的大小和容量都没有扭转,其残余地位还保留了之前存储的元素,此时能够应用erase清理无用的数据:

vecInt.erase(iter, vecInt.end());

倡议:remove()用于删除容器中指定元素后,可应用 erase() 成员函数清理无用数据。
clear:清理容器中所有的元素