zoukankan      html  css  js  c++  java
  • STL中的Vector相关用法

    STL中的Vector相关用法

      标准库vector类型使用需要的头文件:#include <vector>。

      vector 是一个类模板,不是一种数据类型,vector<int>是一种数据类型。

      Vector的存储空间是连续的,list不是连续存储的。

    1. 定义和初始化

    vector< typeName > v1;       //默认v1为空,故下面的赋值是错误的v1[0]=5;
    //v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被扩充为 v1.size()。
    vector<typeName>v2(v1); 或v2=v1;或vector<typeName> v2(v1.begin(), v1.end());
    vector< typeName > v3(n,i);//v3包含n个值为i的typeName类型元素 vector< typeName > v4(n); //v4含有n个值为0的元素 int a[4]={0,1,2,3,3}; vector<int> v5(a,a+5);//v5的size为5,v5被初始化为a的5个值。后一个指针要指向将被拷贝的末元素的下一位置。 vector<int> v6(v5);//v6是v5的拷贝 vector< 类型 > 标识符(最大容量,初始所有值);

    2. 值初始化

      (1)如果没有指定元素初始化式,标准库自行提供一个初始化值进行值初始化。
      (2)如果保存的式含有构造函数的类类型的元素,标准库使用该类型的构造函数初始化。
      (3)如果保存的式没有构造函数的类类型的元素,标准库产生一个带初始值的对象,使用这个对象进行值初始化。

    3. vector对象最重要的几种操作

      (1)v.push_back(t)    在容器的最后添加一个值为t的数据,容器的size变大。

         其中,采用的是复制构造函数重新建立这样的一个对象。  另外list有push_front()函数,在前端插入,后面的元素下标依次增大。
      (2)v.size()        返回容器中数据的个数,size返回相应vector类定义的size_type的值。

         v.resize(2*v.size)或v.resize(2*v.size, 99) 将v的容量翻倍(并把新元素的值初始化为99)
      (3)v.empty()     判断vector是否为空
      (4)v[n]           返回v中位置为n的元素
      (5)v.insert(pointer,number, content)    向v中pointer指向的位置插入number个content的内容。
           还有v. insert(pointer, content),v.insert(pointer,a[2],a[4])将a[2]到a[4]三个元素插入。
      (6) v.pop_back()    删除容器的末元素,并不返回该元素。
      (7)v.erase(pointer1,pointer2) 删除pointer1到pointer2中间(包括pointer1所指)的元素
            vector中删除一个元素后,此位置以后的元素都需要往前移动一个位置,虽然当前迭代器位置没有自动加1,
         但是由于后续元素的顺次前移,也就相当于迭代器的自动指向下一个位置一样。
      (8)v1==v2          判断v1与v2是否相等。
      (9)!=、<、<=、>、>=      保持这些操作符惯有含义。
      (10)vector<typeName>::iterator p=v1.begin( ); p初始值指向v1的第一个元素。*p取所指向元素的值。
          对于const vector<typeName>只能用vector<typeName>::const_iterator类型的指针访问。
      (11)p=v1.end( ); p指向v1的最后一个元素的下一位置。
      (12)v.clear()      删除容器中的所有元素。但是内存空间不变,只是情况所在内容。

      (13)v.reserve()  初始化预留空间,此动作可以与对象定义分开。

      (14)

     3. vector的assign()用法

      vector::assign //用来构造一个vector的函数,类似于copy函数
      void assign( size_type _Count, const Type& _Val);

      注意:

      (1)_Count指要构造的vector成员的个数,   _Val指成员的数值,他的类型必须与vector类型一致!

      (2)这个函数用来,在创建Vector对象后,但是没有对其进行构造容器元素,即将创建对象与构造扩展数据分开。

    template<class InputIterator>
    void assign( InputIterator _First, InputIterator _Last );
    //两个指针,分别指向复制开始和结束的地方!
    EXAMPLE
    // vector_assign.cpp
    // compile with: /EHsc
    #include <vector>
    #include <iostream>
    
    int main( )
    {
       using namespace std;
       vector<int> v1, v2, v3;
       vector<int>::iterator iter;
    
       v1.push_back(10);
       v1.push_back(20);
       v1.push_back(30);
       v1.push_back(40);
       v1.push_back(50);
    
       cout << "v1 = " ;
       for (iter = v1.begin(); iter != v1.end(); iter++)
           cout << *iter << " ";
       cout << endl;
    
       v2.assign(v1.begin(), v1.end());
       cout << "v2 = ";
       for (iter = v2.begin(); iter != v2.end(); iter++)
           cout << *iter << " ";
       cout << endl;
    
       v3.assign(7, 4) ;
       cout << "v3 = ";
       for (iter = v3.begin(); iter != v3.end(); iter++)
           cout << *iter << " ";
       cout << endl;
    }

      输出:

    v1 = 10 20 30 40 50
    v2 = 10 20 30 40 50
    v3 = 4 4 4 4 4 4 4 

      size()成员指当前拥有的元素个数;capacity()成员指当前(容器必须分配新存储空间之前)可以存储的元素个数。reserve()成员可以用来控制容器的预留空间。vector另外一个特性在于它的内存空间会自增长,每当vector容器不得不分配新的存储空间时,会以加倍当前容量的分配策略实现重新分配。例如,当前capacity为50,当添加第51个元素时,预留空间不够用了,vector容器会重新分配大小为100的内存空间,作为新连续存储的位置。

      在调用push_back时,每次执行push_back操作,相当于底层的数组判定是否需要重新分配大小;,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有 的vector并释放原有的内存。例如下面程序:

    #include <iostream>
    #include <cstdlib>
    #include <vector>
    
    using namespace std;
    
    class Point
    {
    public:
            Point()
            {
                cout << "construction" << endl;
            }
            Point(const Point& p)
            {
                cout << "copy construction" << endl;
            }
            ~Point()
            {
                cout << "destruction" << endl;
            }
    };
    
    int main()
    {
        vector<Point> pointVec;
        Point a;
        Point b;
        pointVec.push_back(a);
        pointVec.push_back(b);
    
        cout<<pointVec.size()<<std::endl;
    
        return 0;
    }

      程序输出:

      http://pic002.cnblogs.com/images/2012/426620/2012091215252725.jpg

    4. vector的内存释放

      由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后 erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。 empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存 的回收。

     (1)  如果需要空间动态缩小,可以考虑使用deque。如果非vector不可,可以用swap()来帮助你释放内存。具体方法如下:

    vector<int> nums; 
    nums.push_back(1);
    nums.push_back(1);
    nums.push_back(2);
    nums.push_back(2); 
    vector<int>().swap(nums); //或者nums.swap(vector<int> ())

      或者如下所示,使用一对大括号,意思一样的:

    //加一对大括号是可以让tmp退出{}的时候自动析构
    { 
        std::vector<int> tmp =   nums;  
        nums.swap(tmp); 
    }

       swap()是交换函数,使vector离开其自身的作用域,从而强制释放vector所占的内存空间,总而言之,释放vector内存最简单的方法是 vector<int>.swap(nums)。

      (2)但是如果nums是一个类的成员,不能把 vector<int>.swap(nums)写进类的析构函数中,否则会导致double free or corruption (fasttop)的错误,原因可能是重复释放内存。标准解决方法如下:

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

      (3) 如果Vector中存放的是指针

      如果vector中存放的是指针,那么当vector销毁时,这些指针指向的对象不会被销毁,那么内存就不会被释放。如下面这种情况,vector中的元素时由new操作动态申请出来的对象指针:

    #include <vector> 
    using namespace std; 
    
    vector<void *> v;

      每次new之后调用v.push_back()该指针,在程序退出或者根据需要,用以下代码进行内存的释放:

    for (vector<void *>::iterator it = v.begin(); it != v.end(); it ++) 
        if (NULL != *it) 
        {
            delete *it; 
            *it = NULL;
        }
    v.clear();

    官方说明:   http://www.cplusplus.com/reference/vector/vector/assign/

     
  • 相关阅读:
    win10 UWP button
    内网分享资源
    内网分享资源
    CF724F Uniformly Branched Trees
    win10 UWP FlipView
    win10 UWP FlipView
    win10 UWP FlipView
    搭建阿里云 centos mysql tomcat jdk
    搭建阿里云 centos mysql tomcat jdk
    win10 UWP 申请微软开发者
  • 原文地址:https://www.cnblogs.com/icmzn/p/5058389.html
Copyright © 2011-2022 走看看