C++ ------模拟实现STL中的vector类

模拟实现vector类

  • vector是表示可变大小数组的序列容器
  • 就像数组一样, Vector也采用了连续存储空间来存储元素, 也就是意味着可以采用下标对vector的元素进行访问, 和数组一样高效. 但不像数组, 它的大小是可以改变的 , 而且大小会被容器自动处理
  • 本质来说, vector使用动态分配数组来储存它的元素. 当新元素插入时, 这个数组需要被重新分配大小 ,为了增加存储空间, 它就会分配一个新的数组, 然后将全部元素移到这个数组中去.
  • vector分配控策略 : vector会分配一些额外的空间以适应可能的增长 , 因为存储空间比实际需要的存储空间更大, 不同的库采用不同的策略权衡空间的使用和重新分配.
  • 与其他动态序列容器相比(deques, lists ), Vector在元素访问的时候更高效, 在末尾添加和删除元素相对高效, 对于起亚不在末尾删除和插入的操作, 效率更低
#include <iostream>
#include <assert.h>
#include <string>
#include <vector>
using namespace std;

template<class T>
class Vector
{
  public:
    typedef T* iterator;
    //typedef const T* const_iterator;
   
    iterator end()
    {
      return _finish;
    }

    Vector()
    :_start(nullptr)
    ,_finish(nullptr)
    ,_endofStorage(nullptr)
    {}
    
    ~Vector()
    {
      if(_start)
      {
        cout << "~Vector()" <<endl;
        delete  []_start;
        _start = _finish = nullptr;
      }
    }
       
    Vector(const Vector<T>& v)
    {
      _start = new T[v.Capacity()];
      for(int i = 0 ; i < v.Size(); i++)
      {
        _start[i] = v[i];
      }
      _finish = _start + v.Size();
      _endofStorage = _start + v.Capacity();
    }
    void Swap(Vector<T>& v)
    {
      swap(_start , v._start);
      swap(_finish ,v._finish);
      swap(_endofStorage, v._endofStorage);
    }

    Vector<T>& operator=(Vector<T> v)
    {
      Swap(v);
      return *this;
    }

    size_t Capacity()
    {
      return _endofStorage - _start;
    }
 
    //增加size
    //T()调用默认构造函数,给value赋缺省值
    //因为容器Vector内可以存放任意类型的数据,当类型将T替换时,就会调用对应类型的构造函数
    //C++中内置类型也有对应的构造函数(int() char())
    void Resize(size_t  n , const T& val = T())
    {
      if(n <= Size())
      {
        _finish = _start + n;
      }
      if(n > Capacity())
      {
        Reserve(n);
      }
      while(_finish < _start + n)
      {
        *_finish++ = val;
      }
    }

    //增容
    void Reserve(size_t n)
    {
      size_t num = Size();
      if(n > Capacity())
      {
        T* tmp = new T[n];
        //需深拷贝
        if(_start)
        {
          for(int i = 0 ; i < Size() ; i++)
          {
            tmp[i] = _start[i];
          }
        }
        _start = tmp;
        _finish = _start + num;
        _endofStorage = _start + n;
      }
    }
    
    void PushBack(const T &v)
    {
     if(_finish == _endofStorage)
       {
       size_t newC = Capacity() == 0 ? 1 :Capacity() * 2;
       Reserve(newC);
       }
       
       *_finish = v;
       ++_finish;
       
      
      
     // Insert(end(),v);
    }

    void Insert(iterator pos , T& val)
    {
      size_t len = pos - _start;
      if(_finish == _endofStorage)
      {
        size_t newC = Capacity() == 0 ? 1: 2 * Capacity();
        Reserve(newC);
      }
      //若增容, 会使迭代器失效, 所以需更新迭代器
      pos = _start +len;
      iterator end = _finish - 1 ;
      while(end > pos)
      {
        *end = *(end - 1);
        --end;
      }
      *pos = val;
      ++_finish;
    }
  
    //删除操作也有可能产生迭代器失效问题
    //所以一边遍历一遍删除
    iterator Erase(iterator pos)
    {
      iterator begin = pos + 1;
      while(begin != _finish)
      {
        *(begin - 1) = *begin;
        ++begin;
      }
      --_finish;
      return pos;
    }
      
    size_t Size()
    {
      return _finish - _start;
    }

    void PopBack()
    {
      assert(Size() > 0);
      --_finish;
    }

    T& operator[](size_t pos)
    {
      assert(pos < Size());
      return _start[pos];
    }

    iterator begin()
    {
      return _start;
    }

  private:
    T* _start = nullptr;
    T* _finish = nullptr;
    T* _endofStorage = nullptr;
};

void test()
{
  Vector<int> v;
  v.PushBack(1);
  v.PushBack(1);
  v.PushBack(1);
  v.PushBack(1);
  v.PushBack(1);
  v.PushBack(1);
  v.PushBack(1);
  for (const auto& e : v)
     {
       cout << e << endl;
     }
}

int main()
{
  test();
  return 0;  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值