C++vector 向量容器用法祥解

 vector(向量):
C++中之等同种植多少结构,确切的说是一个类.它相当给一个动态的高频组,当程序员无法知晓自己用的数组的范围多异常时,用其来化解问题可高达最好深省空间的目的.

   用法:

          1.文书包含:     

          
首先以先后开始处加上#include<vector>以富含所要之近乎公事vector

          还有一定要是加上using namespace std;

 

   2.变量宣称:

               2.1 例:声明一个int向量以代替一维的数组:vector <int>
a;(等于声明了一个int数组a[],大小没有点名,可以动态的向其中长去)。

               2.2
例:用vector代替二维数组.其实只要声明一个一维数组向量即可,而一个数组的讳其实代表的凡它的首地址,所以要声明一个地点之向量即可,即:vector
<int *> a.同理想用为量代替三维数组也是一致,vector
<int**>a;再望上面依此类推.

 

 vector类常用的函数如下所示:

    1.构造函数

    vector():创建一个空vector
    vector(int nSize):创建一个vector,元素个数为nSize
    vector(int nSize,const t&
t):创建一个vector,元素个数为nSize,且值均为t
    vector(const vector&):复制构造函数
    vector(begin,end):复制[begin,end)区间内其他一个数组的要素到vector中

    2.搭函数

    void push_back(const T& x):向量尾部增加一个元素X
    iterator insert(iterator it,const T&
x):向量中迭代器指向元素前多一个元素x
    iterator insert(iterator it,int n,const T&
x):向量中迭代器指向元素前多n个相同的元素x
    iterator insert(iterator it,const_iterator first,const_iterator
last):向量中迭代器指向元素前插入另外一个一律类别向量的[first,last)间的数额

   3.剔除函数

    iterator erase(iterator it):删除向量中迭代器指向元素
    iterator erase(iterator first,iterator
last):删除向量中[first,last)中元素
    void pop_back():删除向量中最后一个因素
    void clear():清空向量中拥有因素

  4.不折不扣历函数

    reference at(int pos):返回pos位置元素的援
    reference front():返回首元素的援
    reference back():返回尾元素的援
    iterator begin():返回向量头指针,指向第一单元素
    iterator end():返回向量尾指针,指向向量最后一个元素的产一个位置
    reverse_iterator rbegin():反向迭代器,指向最后一个因素
    reverse_iterator rend():反向迭代器,指向第一独元素之前的职务

  5.论断函数

    bool empty() const:判断向量是否也空,若为空,则向量中无元素

  6.大小函数

    int size() const:返回向量中元素的个数
    int capacity() const:返回时向量张红所能够包容的不过充分长素值
    int max_size() const:返回最可怜可容的vector元素数量值

  7.其他函数

    void swap(vector&):交换两个与种向量的数量
    void assign(int n,const T& x):设置向量中第n只因素的值为x
    void assign(const_iterator first,const_iterator
last):向量中[first,last)中元素设置成时为量元素

vector<int> vecIntA;
//打印vectorA
for(vector<int>::iterator it =
vecIntA.begin();it!=vecIntA.end();it++) 
    { 
        cout<<*it<<”     “; 
    }

 

内存管理暨频率

1》使用reserve()函数提前设定容量大小,避免频繁容量扩展操作造成效率低下。

       
关于STL容器,最让人赞叹之风味有即是凡要不超越她的最好酷尺寸,它们就足以自动增长到好容纳你放上的数据。(要解这太要命价值,只要调用名叫max_size的成员函数。)对于vector和string,如果急需再多空间,就盖类realloc的考虑来增强大小。vector容器支持随机走访,因此为提高效率,它其中使用动态数组的方贯彻之。在经
reserve()
来申请一定大小的当儿总是以指数边界来增大其里面缓冲区。当进行insert或push_back等追加元素的操作时,如果这时动态数组的内存不够用,就设动态的重新分配当前高低的1.5~2加倍之新内存区,再把原先数组的情复制过去。所以,在一般景象下,其访问速度同一般数组,只有当重新分配发生常,其性才会减低。正而上面的代码告诉您的那样。而开展pop_back操作时,capacity并无会见以vector容器里之元素减少而有所下跌,还会维持操作前的分寸。对于vector容器来说,如果发生大量之数要开展push_back,应当用reserve()函数提前设定其容量大小,否则会并发过多蹩脚容量扩展操作,导致效率低下。

     
reserve成员函数允许而太小化必须进行的重新分配的次数,因而可以免真分配的开发和迭代器/指针/引用失效。但当自说reserve为什么可以那么开事先,让我简单介绍有时候令人困惑的季单相关成员函数。在标准容器中,只有vector和string提供了所有这些函数。

(1)
size()告诉您容器中来微微元素。它并未报您容器为它们包容的因素分配了稍稍内存。
(2)
capacity()告诉您容器在其既分配的内存中可包容多少元素。那是容器在那么片内存中总共可容纳多少元素,而无是尚得包容多少元素。如果你想清楚一个vector或string中发出稍许并未为占据的内存,你必须从capacity()中减去size()。如果size和capacity返回同样的值,容器中虽从来不剩余空间了,而下一样不善栽(通过insert或push_back等)会掀起上面的重新分配步骤。
(3) resize(Container::size_type
n)强制将容器改吧容纳n个要素。调用resize之后,size将会晤返回n。如果n小于当前高低,容器尾部的因素会叫销毁。如果n大于当前高低,新默认构造的元素会加加至容器尾部。如果n大于当前容量,在要素加入之前见面发生重新分配。
(4) reserve(Container::size_type
n)强制容器把她的容量改吧至少n,提供的n不小于当前大小。这一般强迫进行相同糟糕重新分配,因为容量需要追加。(如果n小于当前容量,vector忽略它,这个调用什么还无做,string可能把它们的容量减少呢size()和n中大的累累,但string的分寸没有改动。在自身之涉被,使用reserve来打一个string中收拾多余容量一般不如用“交换技术”,那是条款17底主题。)

    
这个简介表示了要有素用插入而且容器的容量不足时即会产生重新分配(包括它维护的原有内存分配和回收,对象的正片和析构和迭代器、指针和援的失效)。所以,避免重新分配的根本是运reserve尽快将容器的容量设置为足够大,最好于容器被组织之后随即开展。

诸如,假得你想建立一个容纳1-1000价值的vector<int>。没有采取reserve,你可像这样来做:

vector<int> v;
for (int i = 1; i <= 1000; ++i) v.push_back(i);
以大部分STL实现着,这段代码在循环过程中将会造成2交10糟重新分配。(10是数没什么意外的。记住vector在重新分配发生常一般将容量翻倍,而1000横齐210。)

拿代码改也以reserve,我们取得这个:

vector<int> v;
v.reserve(1000);
for (int i = 1; i <= 1000; ++i) v.push_back(i);
当时当循环中未见面生出重新分配。

在大大小小及容量之间的涉及被咱得预言什么时候插入将唤起vector或string执行重新分配,而且,可以断言什么时插入会使对容器被的迭代器、指针和援失效。例如,给来就段代码,

string s;

if (s.size() < s.capacity()) {
s.push_back(‘x’);
}
push_back的调用不见面要对是string中之迭代器、指针或引用失效,因为string的容量保证大于它的轻重。如果未是执行push_back,代码在string的任意位置展开一个insert,我们照样可管在插入期间没有生重新分配,但是,与陪同string插入常迭代器失效的貌似规则一样,所有自插入位置及string结尾的迭代器/指针/引用将失效。

回来本条款的主旨,通常有少动静以reserve来避免不必要的重新分配。第一独可用之景况是当您当或者大约了解发生小元素以最终出现于容器中。那样的话,就像上面的vector代码,你只是提前reserve适当数量之半空中。第二种植情况是保存你也许需要之顶老之空间,然后,一旦你补充加完全部多少,修整掉任何多余的容量。

       2》使用“交换技术”来收拾vector过剩空间/内存

     
有一样栽艺术来拿它们起曾经最为特别的容量减少至它本急需之容量。这样减少容量的道常常被喻为“收缩到适当(shrink
to fit)”。该方法才待一漫漫告句:vector<int>(ivec).swap(ivec);
表达式vector<int>(ivec)建立一个临时vector,它是ivec的一致份拷贝:vector的正片构造函数做了这个工作。但是,vector的正片构造函数只分红拷贝的元素用之内存,所以这临时vector没有多余的容量。然后我们于临时vector和ivec交换数据,这时我们得了,ivec只发生临时变量的整过之容量,而以此临时变量则具有了已经在ivec中之没有因此到之森容量。在此地(这个话结尾),临时vector被销毁,因此释放了先ivec使用的内存,收缩到适合。

     3》用swap方法强行释放STL Vector所占用内存

template < class T> void ClearVector( vector<T>& v )
{
    vector<T>vtTemp;
    vtTemp.swap( v );
}

    vector<int> v ;
    nums.push_back(1);
    nums.push_back(3);
    nums.push_back(2);
    nums.push_back(4);
    vector<int>().swap(v);

/* 或者v.swap(vector<int>()); */

/*还是{ std::vector<int> tmp = v;   v.swap(tmp);   }; //加大括声泪俱下{
}是让tmp退出{ }时自动析构*/

 

5.Vector 内存管理成员函数的一言一行测试

       C++
STL的vector使用十分广,但是对那个内存的管制模型一直发多种猜,下面用实例代码测试来询问其内存管理方,测试代码如下:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
vector<int> iVec;
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//1个元素, 容器容量为1

iVec.push_back(1);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//2单要素, 容器容量为2

iVec.push_back(2);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//3个元素, 容器容量为4

iVec.push_back(3);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//4个元素, 容器容量为4

iVec.push_back(4);
iVec.push_back(5);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//5个因素, 容器容量也8

iVec.push_back(6);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//6独因素, 容器容量也8

iVec.push_back(7);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//7独要素, 容器容量为8

iVec.push_back(8);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//8只要素, 容器容量为8

iVec.push_back(9);
cout << “容器 大小为: ” << iVec.size() << endl;
cout << “容器 容量为: ” << iVec.capacity() << endl;
//9只元素, 容器容量也16
/* vs2005/8 容量增长不是翻译倍之,如
    9个元素   容量9
    10个元素 容量13 */

/* 测试effective stl中之非常规之置换 swap() */
cout << “当前vector 的轻重也: ” << iVec.size() <<
endl;
cout << “当前vector 的容量为: ” << iVec.capacity() <<
endl;
vector<int>(iVec).swap(iVec);

cout << “临时之vector<int>对象 的深浅为: ” <<
(vector<int>(iVec)).size() << endl;
cout << “临时的vector<int>对象 的容量也: ” <<
(vector<int>(iVec)).capacity() << endl;
cout << “交换后,当前vector 的大小也: ” << iVec.size()
<< endl;
cout << “交换后,当前vector 的容量为: ” << iVec.capacity()
<< endl;

return 0;
}

6.vector的另成员函数

        c.assign(beg,end):将[beg; end)区间中之数据赋值给c。
        c.assign(n,elem):将n个elem的正片赋值给c。
       
c.at(idx):传回索引idx所负的多少,如果idx越界,抛出out_of_range。
        c.back():传回最后一个多少,不检讨这个数额是否留存。
        c.front():传回地一个数。
        get_allocator:使用构造函数返回一个拷贝。
        c.rbegin():传回一个逆向队列的首先独数据。
        c.rend():传回一个逆向队列的末尾一个数量的下一个职。
        c.~ vector <Elem>():销毁所有数据,释放内存。   

7.备注:在为此vector的经过遭到的片段题材,特此列出讨论:

               1)

                    vector <int > a;

                    int  b = 5;

                    a.push_back(b);

                    此时要对b另外赋值时无见面影响a[0]的值

                2)

                    vector <int*> a;
                     int *b;
                     b= new int[4];
                     b[0]=0;
                     b[1]=1;
                     b[2]=2;
                     a.push_back(b);
                     delete b;          //释放b的地方空间
                     for(int i=0 ; i <3 ; i++)
                     {
                           cout<<a[0][i]<<endl;
                     }

                    
此时出口的价并无是同等开始b数组初始化的价值,而是有无法预测的值.

                    分析:根据1)
2)的结果,可以想到,在1)中, 
往a于量中压入的是b的价值,即a[0]=b,此时a[0]同b是储存于少数单例外的地方被的.因此改变b的价值未会见影响a[0];而当2)中,因为是拿一个地方(指针)压入向量a,即a[0]=b,因此释放了b的地址为就是放了a[0]的地址,因此a[0]数组中存放的数值为不怕不得而知了.