看了前面的介绍今天给大家讲讲vector容器,首先vector就是我们数学中经常说的向量,所有vector容器也就是存放向量的容器,我们可以把他理解成数组
vector提供顺序表,下标运算符[]有效。当vector的内存用尽时,我们需要自动分配更大的连续内存区,将原先的元素复制到新的内存区,然后释放旧的内存区。内存分配是由分配子(allocator)完成.
vector支持随机访问迭代子(相当于指针),可以用来实现队列,堆,栈,列表和其它复杂的结构,也就是说我们学会vector以后就可以用vector代替数组
vector的迭代子通常为实现为vector元素的指针。
1.系统调用
当我们想使用vector类时我们要先添加头文件
#include<vector>
还要特别注意的是我们需要添加标准命名空间
using namespace std;
相当于一个类模板,我们使用时要先用声明向量容器的类型构建一个容器对象
vector<int> a;//定义存放整形序列的向量容器对象a
vector<float> b;//定义存放实形序列的向量容器对象b
vector<char> c;//定义存放字符形序列的向量容器对象c
我们定义好容器对象以后就可以通过对象来调用容器的方法
vector容器的成员方法有很多,下面标红色的是我们日常使用时常见的
assign | 拭除一个向量和指定的元素复制到空的向量。 |
at | 返回位于指定位置处的元素对向量中。 |
back | 返回最后一个向量的元素的引用。 |
begin | 返回一个随机访问迭代器向量中的第一个元素。 |
capacity | 返回向量可能包含未分配更多存储的元素的数目。 |
cbegin | 返回一个随机存取 const 迭代器向量中的第一个元素。 |
cend | 返回一个随机存取 const 迭代器只是向量的末尾之外的点。 |
crbegin | 已冲销的向量中的第一个元素中返回 const 迭代器。 |
crend | 已冲销的向量的末尾返回常量的迭代器。 |
clear | 擦除向量的元素。 |
data | 将指针返回到向量中的第一个元素。 |
emplace | 插入到指定位置的向量构造的元素。 |
emplace_back | 添加一个构造向量的末尾位置中的元素。 |
empty | 测试矢量容器是空的。 |
end | 返回一个随机访问迭代器指向向量的末尾。 |
擦除 | 将向量从指定位置中删除元素或某个范围的元素。 |
front | 在向量中返回的第一个元素的引用。 |
get_allocator | 返回一个对象以 allocator矢量所使用的类。 |
插入 | 插入指定位置的向量的元素的数量。 |
max_size | 返回向量的最大长度。 |
pop_back | 删除末尾的向量的元素。 |
push_back | 将元素添加到向量的末尾。 |
rbegin | 已冲销的向量中的第一个元素中返回迭代器。 |
rend | 已冲销的向量的末尾返回迭代器。 |
reserve | 保留存储为矢量对象的最小长度。 |
resize | 指定新的大小对应于向量。 |
shrink_to_fit | 放弃过多的容量。 |
size | 返回向量中的元素数。 |
2.自主实现vector容器类模板部分功能
当我们想遍历访问容器中的元素时,我们需要借助面向对象指针也就是我们经常说的迭代子(迭代器)来进行访问,这里不做介绍,后续会专门写一篇关于迭代子的博客。
上述是我们采用系统调用来使用vector容器,那么如果让我们自己来实现vector类该怎么实现呢?下面我给大家用代码实现一下这个vector类模板
#include <iostream>
template<typename T>//表明类模板
class vector
{
public:
vector()//构造函数
{
maxsize=2;
arr=new T [2]();
nowsize=0;
printf("构造成功\n");
}
~vector()//析构函数
{
delete[] arr;
arr=NULL;
}
vector(const vector&rhs)
{
arr=new T[rhs.maxsize]();//开辟和rhs同样大的空间
for(int i=0;i<maxsize;i++)//深拷贝,将数据复制过去
{
arr[i]=rhs.arr[i];
}
printf("拷贝构造成功\n");
}
vector& operator =(const vector& rhs)//赋值运算符重载
{
if(&rhs!=this)
{
delete[] arr;//释放现有内存
arr=NULL;
arr=new T [rhs.maxsize]();//开辟和目标一样大的内存空间
maxsize=rhs.maxsize;//变量赋值
nowsize=rhs.nowsize;
for(int i=0;i<nowsize;i++)//拷贝数据
{
arr[i]=rhs.arr[i];
}
}
return *this;
}
void inserthead(T val);//头部插入
void inserttail(T val);//尾部插入
void insertpos(T val,int pos);//根据下标进行插入
void deletehead();//删除第一个元素
void deletetail();//删除最后一个元素
void deletepos(int pos);//根据下标进行删除
T* add();//扩容
void show()
{
for(int i=0;i<nowsize;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
private:
T *arr;
int nowsize;//当前存放的数据个数
int maxsize;//最大可以存放的数据个数
};
template<typename T>
void vector<T>::inserthead(T val)
{
if(maxsize==nowsize)//当前数据个数等于容量时说明满了,所有扩容
{
add();
}
for(int i=nowsize;i>0;i--)
{
arr[i]=arr[i-1];//将所有数据向前移一位
}
arr[0]=val;
nowsize++;
}
template<typename T>
void vector<T>::inserttail(T val)
{
if(maxsize==nowsize)//当前数据个数等于容量时说明满了,所有扩容
{
add();//执行扩容
}
arr[nowsize]=val;
nowsize++;
}
template<typename T>
void vector<T>::insertpos(T val,int pos)
{
if(pos>maxsize-1)
{
printf("位置不合法\n");
return;
}
if(maxsize==nowsize)//当前数据个数等于容量时说明满了,所有扩容
{
add();
}
for(int i=nowsize;i>pos;i--)
{
arr[i]=arr[i-1];//将所有数据向后移一位
}
arr[pos]=val;
nowsize++;
}
template<typename T>
void vector<T>::deletehead()
{
for(int i=0;i<nowsize-1;i++)
{
arr[i]=arr[i+1];//将所有数据向前移一位
}
nowsize--;
}
template<typename T>
void vector<T>::deletepos(int pos)
{
if(pos>maxsize-1)
{
return;
}
for(int i=pos;i<nowsize-1;i++)
{
arr[i]=arr[i+1];//将所有数据向前移一位
}
nowsize--;
}
template<typename T>
void vector<T>::deletetail()
{
nowsize--;
}
template<typename T>
T *vector<T>::add()
{
maxsize=maxsize*2;
T*brr=new T[maxsize]();
for(int i=0;i<maxsize;i++)
{
brr[i]=arr[i];
}
delete []arr;
arr=brr;
return brr;
}
int main()
{
vector<char> a;
vector<char> b(a);
a.inserttail(1);
a.inserttail(3);
a.inserttail(4);
a.insertpos(2,1);
b=a;
a.show();
b.show();
}