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 函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章