我们都知道,数组是静态地分配空间放入对应的元素,一旦配置了就不能改变,若要改变其大小,需要进行“配置新空间->数据移动->释还新空间”的过程,成本代价太高。接下来就体现了vector的优势。
vector功能:实现动态的分配数组,数组元素的大小随着vector对象元素个数变化而变化。
vector的数据结构:线性连续空间,会分配额外的空间以适应可能的增长,这里也体现了容量的观念。
vector的参数:
vector的分配策略:以两个迭代器start和finish分别指向配置得来的连续空间中目前已经被使用的范围。endofstorage指向整块连续(备用空间)的尾端。
关于容量的相关接口:
在这里着重了解resize和capacity
判断容器大小:
int main()
{
int array[3] = { 1, 2, 3,};
vector<int> arr(array, array + 3);
cout << "容器中的元素个数为:" << arr.size() << endl;
cout << endl;
cout << "容器当前的最大容量为:" << arr.capacity() << endl;
cout << endl;
cout << "容器最大可以允许vector的元素数量为:" << arr.max_size() << endl;
cout << endl;
return 0;
}
resize用法:
int main()
{
vector<int> v;
v.resize(5,10);
v.resize(10);
for(int i = 0;i < v.size();i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
v.resize(4);
for(int i = 0;i < v.size();i++)
{
cout<<v[i]<<" ";
}
cout<<endl;
}
resize的函数原型:void resize (size_type n, value_type val = value_type());
最主要的功能是开空间并初始化和截取指定数目的元素。
(1)给定了n,给初始化的值就直接赋值,没有给初始化的就会默认写下T的缺省值,这里是型,所以就补0。
(2)v.resize(4);在这里只保留前四个元素值。
reserve用法:
int main()
{
vector<int> v1;//定义一个数据类型为int的vector
v1.resize(5);
v1.reserve(10);
cout << v1.capacity() << endl; // 10
cout << v1.size() << endl; // 5
v1.reserve(2);
cout << v1.capacity() << endl; //10
}
函数原型为:void reserve (size_type n);
功能:直接增容,节省时间。
(2)如果n大于当前的vector的容量,则该函数会导致容器重新分配其存储空间,使其容量增加到n(或更大)。
(2)如果n小于当前的vector的容量,保留之前capacity值,vector容量不会改变。
编辑修改的相关接口:
在这里我们着重介绍一下插入和删除操作:
Insert用法
int main()
{
vector<int> arr(5, 1);
vector<int>::iterator it;
it = arr.begin();
arr.insert(it+3, 100); //设定插入位置和插入数据
cout << "插入后的元素: ";
for (it = arr.begin(); it < arr.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
Erase用法
int main()
{
std::vector<int> arr;
for(int i =1;i <= 10; i++)
{
arr.push_back(i);
}
cout<<"原始数据:";
for(unsigned i = 0;i <arr.size(); ++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
arr.erase(arr.begin()+6);
arr.erase(arr.begin()+2,arr.begin()+4);//设定插入区间
cout<<"删除后的数据:";
for(unsigned i = 0;i < arr.size();++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
简单地模拟实现MyVector
template<class T>
class MyVector
{
public:
typedef T* Iterator;
typedef const T* ConstIterator;
Vector()
:_statr(NULL)
,_finish(NULL)
,_endofstorage(NULL)
{}
size_t Size()
{
return _finish-_start;
}
size_t Capacity()
{
return _endofstorage-_start;
}
Iterator Begin()
{
return _start;
}
Iterator End()
{
rerurn _finish;
}
void PushBack(const T& x)
{
Iterator end = End();
Iterator(end,x);
}
void Insert(Iterator& pos,const T& x)
{
size_t n = pos-_start;
if(_finish == _endofstorage)
{
size_t len =Size() ==0 ? 3 : 2*capacity();
Expand(len);
}
pos = _start + n;
for(Inerator end =End();end != pos;--end)
{
*(end)=*(end-1);
}
*pos=x;
++_finish;
}
void Reverse(const size_t n)
{
Expand(n);
}
void Expand(size_t n)
{
const size_t size =Size();
const size_t capacity=Capacity();
if (n > capacity)
{
//开辟n空间,拷贝内容
T* tmp = new T[n];
for (size_t i = 0; i < size; i++)
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = _start + size;
_endofstorage = _start + n;
}
}
void PopBack()
{
assert(Size() > 0);
Iterator end = End();
Erase(end);
}
void Erase(Iterator& pos)
{
assert(pos != NULL);
for (Iterator end = pos; end < End(); end++)
{
_start[end-_start] = _start[(end + 1)-_start];
}
--_finish;
}
size_t MaxSize()
{
return (0xffffffff / sizeof(T));
}
void Print()
{
for (size_t i = 0; i < Size(); i++)
{
cout << _start[i] << " ";
}
cout << endl;
}
protected:
Iterator _start;
Iterator _finish;
Iterator _endofstorage;
};