std::vector使用心得

vector容器使用动态分配数组来存储它的元素,支持随机访问。

头文件 #include<vector>
使用名称空间 using std::vector;

目录

常用函数:

vector类模板声明

构造函数

增加

删除

查看

修改

空间和大小

迭代器



常用函数:

vector类模板声明

_Tp:元素类型
std::allocator<_Tp>:_Tp的内存分配器

template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
   ...
};

构造函数

struct data
{
    int a;
    int b;
    data():a(10),b(20){}
    data(int i,int j):a(i),b(j){}
};


1、默认构造函数 vector()
   例:vector<data> v1;
   
2、拷贝构造函数 vector(const vector& __x)
   例:vector<data> v2(v1);
   
3、移动构造函数 vector(vector&& __x) noexcept
   例:vector<data> v3(std::move(v2)); 使用移动构造后v2里面所有元素被移动到v3里面,v2长度变为0
   
4、参数构造函数
  4.1 vector(size_type __n, const allocator_type& __a = allocator_type())
      例:vector<data> v4(5); 插入5个相同的默认构造函数创建的元素,等同于vector<data> v4(5,data());

  4.2 vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type())
      例:vector<data> v5(15,data(1,2)); 插入15个相同的data(1,2)创建的元素,也可以这样写vector<data> v5(5,{1,2});

  4.3 vector(initializer_list<value_type> __l,  const allocator_type& __a = allocator_type())
      例:vector<data> v6{{0,1},{2,3},{4,5},{6,7}}; 创建包含4个不同data元素的向量

  4.4 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type())
      例:vector<data> v7(v6.begin(),v6.begin()+3);	使用其他向量元素创建
	  
5、普通赋值函数 vector& operator=(const vector& __x)
   例:vector<data> v8 = v7;
   
6、移动赋值函数 vector& operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
   例:vector<data> v9 = std::move(v8); 使用移动构造后v8里面所有元素被移动到v9里面,v8长度变为0
   
7、初始化列表赋值 vector& operator=(initializer_list<value_type> __l)
   例:vector<data> v10 = {{0,1},{2,3},{4,5},{6,7}};

增加

std::vector<int> mlist;

1、void      push_back(const value_type& __x);
   末尾添加元素
   mlist.push_back(1);

2、void      emplace_back(_Args&&... __args);
   末尾添加元素,底层实现直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程 C++ 11 标准新增加的,建议优先选用emplace_back()
   mlist.emplace_back(2);   

3、iterator   emplace(iterator __position, _Args&&... __args);
   任意位置插入元素,省去了拷贝或移动元素的过程 ,第一个参数一定要在num迭代器区间[bengin(),end()],返回插入元素位置的迭代器
   mlist.emplace(mlist.end(),3);//末尾插入3
   mlist.emplace(mlist.end());  //末尾插入默认值

4、iterator      insert(iterator __position, const value_type& __x);
   任意位置插入元素,第一个位置参数一定要在num迭代器区间[bengin(),end()]
   mlist.insert(mlist.end(),8);

5、iterator      insert(iterator __position, value_type&& __x)
   任意位置插入元素,第一个位置参数一定要在num迭代器区间[bengin(),end()]
   mlist.insert(mlist.end(),8);

6、void      insert(iterator __position, initializer_list<value_type> __l)
   mlist.insert(mlist.begin(),{100,200,300}); //开始位置插入100,200,300

7、void      insert(iterator __position, size_type __n, const value_type& __x)
   mlist.insert(mlist.begin(),2,555); //开始位置插入两个555

8、void     insert(iterator __position, _InputIterator __first, _InputIterator __last)
   mlist.insert(mlist.begin(),mlist.begin(),mlist.end());

删除

1、void      clear();
   清空向量元素,不会删除内存空间,size变为0,预留空间capacity大小不变

2、iterator     erase(iterator __position);
   删除pos位置元素,删除前确定pos是否正常范围内[begin(),end())

3、iterator      erase(iterator __first, iterator __last);
   删除[__first,__last)区间位置元素,删除前确定pos是否正常范围内[begin(),end())	

4、void  pop_back();
   删除末尾元素,必须先判空,不然返回不存在的元素导致段错误

查看

1、bool      empty() const;
   向量判空

2、reference      at(size_type __n);
3、const_reference      at(size_type __n)
   访问第__n个元素引用,会检查是否越界是则抛出out of range异常
   
4、reference      operator[](size_type __n)
   下标访问元素,__n注意不要越界
   []访问越界不会抛出异常,能正常往下执行,非常危险出问题也很难定位

5、reference      front();
6、const_reference      front() const
   访问第一个元素,必须先判空不然返回不存在的元素导致段错误

7、reference      back();
8、const_reference      back();
   访问最后一个元素,一定要先判断是否为空,否则会出现指针越界

9、 _Tp* data();
10、const _Tp*data() const
   返回一个指针,vector在内存中就是一个连续存储的数组,所以可以返回一个指针指向这个数组

修改

assign函数重新分配向量

1、void assign(size_type __n, const value_type& __val);
   vector<int> v1 = {1,2,3,4,5};   
   v1.assign(2,123);//修改后v1为{123,123}

2、void assign(_InputIterator __first, _InputIterator __last)
   注意:赋值为[__first,__last)前闭后开
     2.1 __first与__last必须是同一个向量的迭代器
     2.2 __first与__last不能超出迭代器范围,比如v1.begin()-1或v1.end()+1超出迭代器范围
     2.3 __first与__last为调用者本身的迭代器可能预想不到结果
   vector<int> v1 = {1,2,3,4,5};
   vector<int> v2 = {1,2,3,4,5};
   vector<int> v3;
   v3.assign(v1.begin(), v1.end())         // 结果v3={1,2,3,4,5}
   v3.assign(v1.begin()+1, v1.begin()+3)   // 结果v3={2,3},前闭后开[2,3,4)
   v3.assign(v1.begin(), v2.end())   //错误使用__first与__last不是同一个向量的迭代器
   v3.assign(v1.begin(), v1.end()+1) //错误使用v1.end()+1 超出迭代器范围
   v1.assign(v1.rbegin(),v1.rend()); //调用v1的assign函数,传入参数为v1本身的迭代器,结果是{5,4,3,4,5},而不是{5,4,3,2,1}

3、void assign(initializer_list<value_type> __l)
   vector<int> v1;
   v1.assign({11,22,33});
   等同于
   vector<int> tmp= {11,22,33};
   v1.assign(tmp.begin(),tmp.end());

4、交换两个向量 void swap(vector& __x);
   vector<int> v1 = {1,2,3,4,5,6};//capacity=6
   vector<int> v2 = {4,5,6};  //capacity=3
   v1.swap(v2);  //结果v1={4,5,6};v1的capacity=3; v2={1,2,3,4,5,6};v2的capacity=6;
   常用于清空向量占用内存 vector<int> tmp.swap(v2);清空v2内存占用
   

空间和大小

1、void      reserve(size_type __n);
   增加预留空间,只增加capacity空间,size不会改变,如果__n小于capacity则capacity大小不会变化
   提前多分配空间,避免执行过程中多次分配内存空间带来性能损耗

2、void      resize(size_type __new_size);
   重新设置size大小;
   __new_size大于原来size则使用默认值填充,同时capacity空间大小等于__new_size;
   __new_size小于原来size则调整size大小,capacity大小不变	

3、void      resize(size_type __new_size, const value_type& __x)
   __new_size大于原来size则使用传入__x值进行填充,同时capacity空间大小等于__new_size;
   
4、void      shrink_to_fit();
   减小capacity空间大小使其等于size大小	

5、size_type      size() const; 
   获取实际存储元素数量	

6、size_type      max_size() const; 
   获取向量最大容量 unsigned int(-1)/sizeof(_Tp);	//__TP元素类型

7、size_type      capacity() const;
   向量真实容量大小,以初始大小成倍数增长std::vector<Type> num(6);以初始大小6成倍数增长	

迭代器

正向迭代器(++是从前往后遍历)
    iterator begin();
    开始迭代器,++从前往后走	

    iterator end();
    迭代器结束位置,常用于结束判断	

    const_iterator  cbegin();
    指向常量的开始迭代器std::vector<int>::const_iterator	

    const_iterator  cend();
    指向常量的末尾迭代器,常用于结束判断	

反向迭代器(++是从后往前遍历)
    reverse_iterator  rbegin();
    指向末尾迭代器,++是从后往前走	

    reverse_iterator  rend();
    指向开始迭代器,常用于结束判断	

   const_reverse_iterator  crbegin();
    指向常量的末尾迭代器,++是从后往前走	

    const_reverse_iterator  crend();
    指向常量的开始迭代器,常用于结束判断

使用实例:

    vector<int> v1 = {1,2,3,4,5};
    vector<int>::iterator it;
    for(it = v1.begin(); it!=v1.end(); it++)//将循环输出1,2,3,4,5
    {
        cout<<*it<<endl;
		*it = 11;
    }

    v1 = {1,2,3,4,5};
    vector<int>::const_iterator it;
    for(it = v1.begin(); it!=v1.end(); it++)
    {
        cout<<it->a<<endl;
        //it->a = 11; //const_iterator 时不能修改
    }

    vector<int>::reverse_iterator it; 
    for(it = v1.rbegin(); it!=v1.rend(); it++) //将倒序输出5,4,3,2,1
    {
        cout<<*it<<endl;
        *it = 11;
    }

    v1 = {1,2,3,4,5};	
    vector<int>::const_reverse_iterator it; 
    for(it = v1.rbegin(); it!=v1.rend(); it++)//将倒序输出5,4,3,2,1
    {
        cout<<*it<<endl;
        //*it = 11; //const_reverse_iterator 不能修改
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值