在实现vector容器之前,我们要先了解STL中的各大组件之前的关系:
从图片中,我们可以看出vector容器是基于空间配置器和迭代器的基础上实现的。用过STL都知道,每一个容器都有自己的专属迭代器,然后这些容器都有相同之处,也有不同之处。因此我们只需要每个容器的迭代器都继承同一个迭代器的基类,去实现我们各自的迭代器。下面首先实现的就是迭代器,在STL源码剖析这个书中,vector迭代器迭代器就是一个指针,但是,本人理解不太符合STL的架构,STL架构中明显每个迭代器都要继承迭代器基类,因此本人设计的迭代器也是继承了基类的迭代器。
//iterator_vector.h
#ifndef VECTOR_ITERATOR_H_INCLUDED
#define VECTOR_ITERATOR_H_INCLUDED
#include"my_iterator_base.h"
namespace juine
{
template<typename _T>
class Iterator_vector:public Iterator_base<_T>
{
public:
typedef random_access_iterator_tag iterator_category;
//构造函数,copy构造函数,copy函数
Iterator_vector(_T* p=0):Iterator_base<_T>(p){}
Iterator_vector(const Iterator_vector& iter):Iterator_base<_T>(iter.point){}
Iterator_vector operator=(Iterator_vector iter)
{
this->point=iter.point;
return *this;
}
//注意 ,好好理解析构函数该怎么写
~Iterator_vector(){}
//随机迭代器能够支持迭代器+,-,--操作
Iterator_vector& operator++()
{
this->point++;
return *this;
}
Iterator_vector operator++(int)
{
Iterator_vector tmp=*this;
++*this;
return tmp;
}
Iterator_vector operator+(size_t n)
{
Iterator_vector iter;
iter.point=(this->point)+n;
return iter;
}
Iterator_vector operator--()
{
this->point--;
return *this;
}
Iterator_vector operator--(int)
{
Iterator_vector tmp=*this;
--*this;
return tmp;
}
Iterator_vector operator-(size_t n)
{
Iterator_vector iter;
iter.point=(this->point)-n;
return iter;
}
int operator-(Iterator_vector iter)
{
return (this->point)-iter.point;
}
bool operator<=(Iterator_vector iter)
{
return this->point<=iter.point;
}
//返回迭代器中的指针(这不是一个好办法,暴漏的内部实现细节)
typename Iterator_base<_T>::pointer& get_pointer()
{
return this->point;
}
};
}
#endif // VECTOR_ITERATOR_H_INCLUDED
接下来是容器的实现,从我们使用vector就可以看出,vector的成员变量应该就是iterator,用来指示容器的起始地址和终止地址的。其实现如下:
//my_vector.h
#ifndef MY_VECTOR_H_INCLUDED
#define MY_VECTOR_H_INCLUDED
#include"iterator_vector.h"
#include"my_iterator_function.h" //for my_distance
#include"simple_allocator.h" //for simple_alloc
#include<cstddef> //for ptrdiff_t
#include<cstdlib>
using std::cout;
using std::endl;
namespace juine
{
template<typename T,typename ALLOC=my_alloc>
class my_vector
{
public:
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef size_t size_type;
typedef Iterator_vector<T> iterator; //vector<int>::iterator
typedef simple_allocator<T,ALLOC> data_container;
private:
iterator start;
iterator finish;
iterator end_of_range;
protected:
void fill_uninitialized(size_t n,value_type value)
{
pointer p =data_container::alloc(n);
uninitialized_fill_n(p,n,value);
start.get_pointer()=p;
finish=start+n;
end_of_range=finish;
}
void fill_uninitialized(Iterator_base<T> first,Iterator_base<T> last)
{
int n=last-first;
pointer p =data_container::alloc(n);
pointer temp=p;
while(first!=last)
{
construct(p,*first);
p++;
first++;
}
start.get_pointer()=temp;
finish=start+n;
end_of_range=finish;
}
void fill_uninitialized(pointer first,pointer last)
{
int n=last-first;
pointer p =data_container::alloc(n);
pointer temp=p;
while(first<last)
{
construct(p,*first);
p++;
first++;
}
start.get_pointer()=temp;
finish=start+n;
end_of_range=finish;
}
/*template<class InputIterator>
void fill_uninitialized(InputIterator first,InputIterator last)
{
int n=last-first;
pointer p =data_container::alloc(n);
pointer temp=p;
while(first!=last)
{
construct(p,*first);
p++;
first++;
}
start.get_pointer()=temp;
finish=start+n;
end_of_range=finish;
}*/
//容器在不需要以后释放内存
void dealloc()
{
cout<<"容器释放内存!"<<endl;
destroy(start.get_pointer(),finish.get_pointer());
data_container::dealloc(start.get_pointer());
}
public:
explicit my_vector():start(0),finish(0),end_of_range(0){ cout<<"默认vector构造函数"<<endl;}
explicit my_vector(int n,int value):end_of_range(0)
{
fill_uninitialized(n,value);
}
my_vector(pointer first,pointer last):end_of_range(0)
{
fill_uninitialized(first,last);
}
my_vector(const Iterator_base<T>& first,const Iterator_base<T>& last):end_of_range(0)
{
fill_uninitialized(first,last);
}
/*template<class InputIterator>
my_vector(InputIterator first,InputIterator last):end_of_range(0)
{
fill_uninitialized(first,last);
}*/
~my_vector(){ dealloc() ;}
iterator& begin(){ return start; }
iterator& end(){ return finish; }
size_type size(){ return finish-start; }
size_type capacity(){ return end_of_range-start; }
bool empty(){ return start==finish; }
value_type& front(){ return *start; }
value_type& back(){ return *(finish-1); }
value_type& operator[](size_type n)
{
iterator iter=start+n;
return *iter;
}
value_type& at(size_type n)
{
iterator iter=start+n;
if(finish<=iter)
{
cout<<"out of memory"<<endl;
exit(1);
}
return *iter;
}
void pop_back()
{
finish--;
destroy(finish.get_pointer());
}
void insert(iterator position,value_type value)
{
if(end_of_range!=finish)
{
iterator temp=finish;
while(temp!=position)
{
*temp=*(temp-1);
temp--;
}
construct(position.get_pointer(),value);
finish++;
}
else
{
size_type len=(size()==0)?1:size()*2;
size_type length=size()+1;
pointer p=data_container::alloc(len);
pointer temp=p;
iterator first=start;
iterator last=finish;
while(first!=last)
{
construct(p,*first);
p++;
first++;
}
construct(p,value);
//释放掉以前的内存,防止内存泄漏
destroy(start.get_pointer(),finish.get_pointer());
data_container::dealloc(start.get_pointer());
start.get_pointer()=temp;
finish=start+length;
end_of_range=start+len;
}
}
template<class InputIterator>
void insert(iterator position,InputIterator first,InputIterator last)
{
int num=last-first;
if((end_of_range-finish)>=num)
{
iterator my_temp=finish+(num-1);
while(my_temp!=(position+(num-1)))
{
*my_temp=*(my_temp-num);
my_temp--;
}
while(first!=last)
{
construct(position.get_pointer(),*first);
position++;
first++;
}
finish=finish+num;
}
else
{
size_type len=(capacity()>(size_type)(last-first)*2)?capacity()*2:(capacity()+(last-first)*2);
size_type length=size()+(last-first);
pointer p=data_container::alloc(len);
pointer temp=p;
iterator temp1=start;
while(temp1!=position)
{
construct(p,*temp1);
p++;
temp1++;
}
while(first!=last)
{
construct(p,*first);
p++;
first++;
}
while(temp1!=finish)
{
construct(p,*temp1);
p++;
temp1++;
}
//释放掉以前的内存,防止内存泄漏
destroy(start.get_pointer(),finish.get_pointer());
data_container::dealloc(start.get_pointer());
start.get_pointer()=temp;
finish=start+length;
end_of_range=start+len;
}
}
void push_back(value_type value){ insert(finish,value); }
void erase(iterator position)
{
if(finish<=position)
{
cout<<"删除已越界,失败!"<<endl;
return ;
}
while(position!=finish-1)
{
*position=*(position+1);
++position;
}
pop_back();
}
void erase(iterator first,iterator last)
{
if(last==finish)
{
destroy(first.get_pointer(),last.get_pointer());
finish=first;
}
else
{
iterator temp=last;
iterator temp1=first;
while(temp!=finish)
{
*temp1=*temp;
temp1++;
temp++;
}
int len=my_distance(first,last);
destroy((finish-len).get_pointer(),finish.get_pointer());
finish=finish-len;
}
}
void clear(){ erase(start,finish); }
};
}
#endif // MY_VECTOR_H_INCLUDED
然后就是测试代码:
//test_vector.cpp
#include<iostream>
#include<typeinfo>
#define _USE_ALLOC
#include"my_vector.h"
using namespace std;
using namespace juine;
int main()
{
int a[6]={1,2,3,4,5,6};
my_vector<int> vec(a,a+6);
vec.back()+=vec.front();
vec.front()+=vec.back();
my_vector<int>::iterator iter;
for(iter=vec.begin();iter!=vec.end();iter++)
cout<<*iter<<endl;
cout<<"3:"<<vec[3]<<endl;
cout<<"1:"<<vec.at(1)<<endl;
cout<<"大小为:"<<vec.size()<<endl;
cout<<"删除:"<<endl;
vec.erase(vec.begin()+3,vec.end()-1);
for(iter=vec.begin();iter!=vec.end();iter++)
cout<<*iter<<endl;
my_vector<int> vec1(4,4);
vec1.push_back(1);
cout<<"capacity:"<<vec1.capacity()<<endl;
vec1.push_back(2);
cout<<"插入:"<<endl;
vec1.insert(vec1.begin()+1,vec.begin(),vec.end());
for(iter=vec1.begin();iter!=vec1.end();iter++)
cout<<*iter<<endl;
cout<<"容量:"<<vec1.capacity()<<endl;
return 0;
}
结果截图:
从运行结果上来看,已基本实现STL容器vector的功能,已达到我们的预期