STL仿写---vector

代码:

void destroy(T* pointer)
{
  pointer->~T();
}

template<class ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last)
{
  for(ForwardIterator it = first; it != last; ++ it)
  {
    destroy(&*it);
  }
}


template<class T>
class MyVector
{
public:
  typedef T  value_type;

  typedef T* iterator;
  typedef const T*const_iterator;

  typedef T* pointer;
  typedef const T* const_pointer;

  typedef T& reference;
  typedef const T& const_reference;

  typedef size_t size_type;

  //默认构造函数
  MyVector();
  //构造函数1:第一个参数为初始化为多少个值,第二个带默认参数,初始化的值为多少
  MyVector(size_type n, const T& value = T());
  //构造函数2:用另外一个容器初始化这个容器,值的类型一样
  MyVector(iterator begin, iterator end);
  //一下两个构造函数说明,vector容器的初始化个数不能超过int,long
  MyVector(int n,const T& value = T());
  MyVector(long n,const T&value = T());
  //析构函数
  ~MyVector();
  
  //复制构造函数
  MyVector(const MyVector&);
  MyVector& operator=(const MyVector&);

  //const原因就是如果对象是个const值的话
  //检查是否为空
  bool empty() const{ return begin() == end();}
  //容器的size()
  size_type size() const {return (size_type)(finish - start);}
  //容器的capacity()
  size_type capacity() const {return (size_type)(end_of_storage - start);}
  
  //开始迭代器
  iterator begin() { return start; }
  const_iterator begin() const{ return start; }

   //尾迭代器
  iterator end()   { return finish;}
  const_iterator end() const{ return finish; }

  //重载[]
  reference operator[](size_type i){return *(start + i);}
  const_reference operator[](size_type i)const {return *(start + i);}

  //插入操作,考虑的情况为是否需要扩增容量
  void insert(iterator position, size_type n, const T& value);
  
  void push_back(const T& value);
  void pop_back();

  void erase(iterator first, iterator last);
  void clear();

  void reserve(size_type n);
protected:
  void fill_initialize(size_type n,const T&value);
protected:
  iterator start;   //空间的头
  iterator finish;  //空间的尾
  iterator end_of_storage; //可用空间的尾巴
private:
  static std::allocator<T> alloc; // object to get raw memory
};

// static class member needed to be defined outside of class
template<class T>
std::allocator<T> MyVector<T>::alloc;

// default constructor
template<class T>
MyVector<T>::MyVector()
  : start(NULL), finish(NULL), end_of_storage(NULL)
{
}

template<class T>
MyVector<T>::MyVector(size_type n, const T& value)
{
    fill_initialize(n,value);
}

template<class T>
MyVector<T>::MyVector(int n,const T& value = T()){
    
    fill_initialize(n,value);
}

template<class T>
MyVector<T>::MyVector(long n,const T&value = T()){
    
    fill_initialize(n,value);
}

template<class T>
MyVector<T>::MyVector(iterator begin, iterator end)
{
    const size_type n = end - begin;
    start = alloc.allocate(n);
    end_of_storage = start+n;
    finish = start+n;

    //uninitialized_copy与copy的不同,拷贝的目的空间如果是未构造的,则用uninitialized_copy
    std::uninitialized_copy(begin, end, start);
}

template<class T>
MyVector<T>::~MyVector()
{
  /* call destructor */
  ::destroy(start, finish);

  /* free space */
  alloc.deallocate(start, end_of_storage - start);
}

// copy control
template<class T>
MyVector<T>::MyVector(const MyVector& rhs)
{
  start = alloc.allocate(rhs.capacity());
  std::uninitialized_copy(rhs.start, rhs.finish, start);
  finish = start + (rhs.finish - rhs.start);
  end_of_storage = start + (rhs.end_of_storage - rhs.start);
}

template<class T>
MyVector<T>& MyVector<T>::operator=(const MyVector& rhs)
{
    start = alloc.allocate(rhs.capacity());
    finish = start + rhs.size();
    end_of_storage = start + start + rhs.size();
  
    std::uninitialized_copy(rhs.begin(), rhs.finish(), start);
    return *this;
}

template<class T>
void MyVector<T>::insert(iterator position, size_type n, const T& value)
{   
    //当容器还剩的位置够插入
  if(n <= end_of_storage - finish)
  {/* enough memory */
    if(n <= finish - position)
    {
      std::uninitialized_copy(finish-n, finish, finish);
      std::copy(position, finish-n, position+n);
      std::fill_n(position, n, value);
    }
    else
    {
      std::uninitialized_fill_n(finish, n - (finish - position), value);
      std::uninitialized_copy(position, finish, position + n);
      std::fill(position, finish, value);
    }
    finish += n;
  }
  else
  {/* reallocate */
    pointer new_start(NULL), new_finish(NULL);
    size_type old_type = end_of_storage - start;
    size_type new_size = old_type + std::max(old_type, n);
    new_start = alloc.allocate(new_size);

    // copy old vector to new vector
    new_finish = std::uninitialized_copy(start, position, new_start);
    std::uninitialized_fill_n(new_finish, n, value);
    new_finish += n;
    new_finish = std::uninitialized_copy(position, finish, new_finish);

    alloc.deallocate(start, end_of_storage - start);

    start = new_start;
    finish = new_finish;
    end_of_storage = new_start + new_size;
  }
}

template<class T>
void MyVector<T>::push_back(const T &value)
{
  insert(end(), 1, value);
}

template<class T>
void MyVector<T>::pop_back()
{
  alloc.destroy(--finish);
}

template<class T>
void MyVector<T>::erase(iterator first, iterator last)
{
  iterator old_finish = finish;
  finish = std::copy(last, finish, first);
  ::destroy(finish, old_finish);
}

template<class T>
void MyVector<T>::clear()
{
  erase(start, finish);
}

template<class T>
void MyVector<T>::reserve(size_type n)
{
  if(capacity() < n)
  {
    iterator new_start = alloc.allocate(n);
    std::uninitialized_copy(start, finish, new_start);

    ::destroy(start, finish);
    alloc.deallocate(start, size());

    const size_type old_size = finish - start;
    start = new_start;
    finish = new_start + old_size;
    end_of_storage = new_start + n;
  }
}

template<class T>
void MyVector<T>::fill_initialize(size_type n,const T&value){
    start = alloc.allocate(n);
    end_of_storage = start+n;
    finish = end_of_storage;
    
    for(iterator i = start;i != finish;i++){
        alloc.construct(i,value);
    }
}
我的收获:

1.我知道了vector的容量为啥不能超过 int 大小。
2. copy 和 uninitialized_copy,fill_n 和 uninitialized_fill_n 的区别,有前缀 uninitialized 表示在未构造的地方进行修改,详细的使用可以看 insert 函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值