菜鸟笔记
提升您的技术认知

自己动手实现vector容器-ag真人游戏

本文参考了侯捷的 《stl 源码分析》一书,出于兴趣,自行实现了简单的 vector 容器。

之后会陆续上传 list, deque 等容器的代码,若有错误,欢迎留言指出。

vector 容易实现的几点注意事项:

1. 由于vector 是动态数组。

出于效率的考虑,在往vector 中加入元素时,内存的扩展遵循的规则是:

   1> 如果当前可用内存不够,开 2倍大的内存,将原来的数组复制到新数组中,撤销原来的数组。

   2> 加入新的元素

2. 通常当我们 int *p = new int(1)时, new 其实做了两件事情: 1> 分配内存   2>在分配的内存中调用类的构造函数

出于效率的考虑,在 vector 的内存管理中,我们将这两个操作分开。

c 提供了 模板类 allocator 来实现上述的功能。

3. vector 中三个指针,分别是 start, finish, end_of_storage;

    [start, finish) 就是数组元素;

    [finish, end_of_storage) 是预先分配的空间(还没有调用构造函数)

参考书籍:

1. c primer, lippman

2. stl 源码分析, 侯捷

// last update:2014-04-11 15:44:44
/**
 * @file vector.h
 * @brief a simple vector class
 * @author [email protected]
 * @version 0.1.00
 * @date 2014-04-09
 */
#ifndef my_vector_h
#define my_vector_h
#include 
#include 
#include 
template
void destroy(t* pointer)
{
  pointer->~t();
}
template
void destroy(forwarditerator first, forwarditerator last)
{
  for(forwarditerator it = first; it != last;    it)
  {
    destroy(&*it);
  }
}
template
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();
  myvector(size_type n, t value = t());
  myvector(iterator begin, iterator end);
  ~myvector();
  //copy control
  myvector(const myvector&);
  myvector& operator=(const myvector&);
  bool empty() const { return begin() == end(); }
  size_type size() const {return (size_type)(finish - start);}
  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:
  iterator start;   //空间的头
  iterator finish;  //空间的尾
  iterator end_of_storage; //可用空间的尾巴
private:
  static std::allocator alloc; // object to get raw memory
};
// static class member needed to be defined outside of class
template
std::allocator myvector::alloc;
// default constructor
template
myvector::myvector()
  : start(null), finish(null), end_of_storage(null)
{
}
template
myvector::myvector(size_type n, t value)
{
  start = alloc.allocate(n);
  end_of_storage = finish = start   n;
  for(iterator i=start; i!=finish;   i)
    alloc.construct(i, value);
}
template
myvector::myvector(iterator begin, iterator end)
{
  const size_type n = end - begin;
  /* allocate space */
  start = alloc.allocate(n);
  finish = end_of_storage = start   n;
  /* call constructor */
  std::uninitialized_copy(begin, end, start);
}
template
myvector::~myvector()
{
  /* call destructor */
  ::destroy(start, finish);
  /* free space */
  alloc.deallocate(start, end_of_storage - start);
}
// copy control
template
myvector::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
myvector& myvector::operator=(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;
  return *this;
}
template
void myvector::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
void myvector::push_back(const t &value)
{
  insert(end(), 1, value);
}
template
void myvector::pop_back()
{
  alloc.destroy(--finish);
}
template
void myvector::erase(iterator first, iterator last)
{ 
  iterator old_finish = finish;
  finish = std::copy(last, finish, first);
  ::destroy(finish, old_finish);
}
template
void myvector::clear()
{
  erase(start, finish);
}
template
void myvector::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;
  }
}
#endif  /*my_vector_h*/

自己动手实现list容器

网站地图