vector容器使用动态分配数组来存储它的元素,支持随机访问。
头文件 #include<vector>
使用名称空间 using std::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 不能修改
}