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/

     
  • 相关阅读:
    Vxlan基础理解
    ODPS基础
    关系型和非关系型数据库的区别?
    交换机的互连技术
    MYSQL 查看最大连接数和修改最大连接数
    Ceph添加/删除Mon(ceph.conf)
    java 线程的几个注解
    UML建模之类图
    单例模式的N种写法
    java工具jar包—Lombok
  • 原文地址:https://www.cnblogs.com/icmzn/p/5058389.html
Copyright © 2011-2022 走看看