<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">背景:</span></span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">背景:</span></span>
在c++ STL中 每一种容器都有其自己对应的迭代器实现。迭代器也成为了算法和容器之间的桥梁。今天先模拟一下vector 容器,以及对应的迭代器。
想法:
一、vector实质是可变长的数组(空间连续),所谓的可变长其实是伪可变长。为了实现可变长,vector的工作实质:
1、初始分配空间大小时,分配按实际需求分配。
2、加入分配空间已经使用满了,再执行一次push_back会发生什么情况?其实是重新申请一个更大的空间(大约原有空间的1.5倍---vs2013),将原来空间的内容拷贝到现有的空间,然后再把需要压入的数追加到后面,最后,释放掉原有的空间。
根据第二条,我们就会发现,其实vector的可变长不是在原来空间上增加空间,而是寻求了更大的一块空间。所以叫伪可变长。
二、vector 的迭代器实质其实是指针,通过观察vector的迭代器实现的功能。operator++,operator==,operator!=,
operator *等,就会发现,其实,普通指针就天生具备,vector支持随机存取,普通指针也有这功能,所以,vector提供的就是Random Access iterators。
程序实现:
<span style="font-size:14px;">#include<iostream>
using namespace std;
template<class T>
class MyVec
{
public:
typedef T* Iterator ;
typedef size_t size_type;
/* 构造函数 */
public:
MyVec():start(0),finish(0),end_of_storage(0){};
MyVec(Iterator p,int n);
MyVec(int num,int value);
~MyVec(){};
/* 成员函数 */
public:
Iterator begin(){return start;}
Iterator end(){return finish;}
size_type size() const {return (finish - start);}
size_type capacity() const {return (end_of_storage - start);}
bool empty() {return start==finish;}
T& operator[](int n) {return n>=0?*(start+n):*(finish+n);}
void push_back(const T&x);
void clear();
Iterator erase(Iterator ite) {
if(++ite!=finish)
memmove(ite,ite+1,(finish-ite-1)*sizeof T);
--finish;
return ite;
}
private:
Iterator start; //使用空间头
Iterator finish;//使用空间尾
Iterator end_of_storage;//可用空间尾
};
template<class T>
MyVec<T>::MyVec(Iterator p,int n)
{
start=new T[n];
for(int i=0;i<n;i++)
*(start+i)=*(p++);
finish=start+n;
end_of_storage=start+n;
}
template<class T>
MyVec<T>::MyVec(int num,int value)
{
start=new T[num]();
finish=start+num;
end_of_storage=start+num;
}
template<class T>
void MyVec<T>:: push_back(const T&x)
{
if (finish!= end_of_storage)
{
*finish=x;
++finish;
}
else
{
const size_type old_size = size();
const size_type len = old_size!=0?2*old_size:1;
Iterator newstart=new T[len];
Iterator newfinish=newstart;
memmove(newstart,start,(sizeof T)*size() );
delete [] start;
start=newstart;
*(start+old_size)=x;
finish=start+old_size+1;
end_of_storage=start+len;
}
}
template<class T>
void MyVec<T>:: clear() //clear 以后可用容量 不会发生变化,但是使用容量变为 0 暂且不改变值 只是将start 指向的值改为0
{
if (size()==0)
return;
finish=start;
*start=0;
}
int main()
{
/* 构造函数和容器预留空间的大小 */
int data[10]={0,1,2,3,4,6,7,8,9};
MyVec<int> vec; //验证默认的构造函数
MyVec<int > vec1(20,8); //验证初始化一样值的构造函数
MyVec<int > vec2(data,10);// 验证用数组初始化的构造函数
cout<<"vec.capacity= "<<vec.capacity()<<endl;
cout<<"vec.capacity= "<<vec1.capacity()<<endl;
cout<<"vec.capacity= "<<vec2.capacity()<<endl;
vec1.push_back(1);
cout<<"vec1 after relocate capacity = "<<vec1.capacity(); //原有容量的两倍
/* 遍历 */
MyVec<int>::Iterator it=vec1.begin();
for(;it!=vec1.end();it++)
cout<<*it<<" ";
cout<<endl;
/* 擦除某元素和检验operator[] */
vec1.erase(it-3);
for(int i=0;i<vec1.size();i++)
cout<<vec1[i]<<" ";
cout<<endl;
/* 其他的成员函数 */
cout<<vec1.empty()<<endl;
vec1.clear();
cout<<vec1.size()<<endl;
}</span>