C++初阶(十三)vector

简介: C++初阶(十三)vector

一、vector的介绍


vector的文档介绍

  1. vector是表示可变大小数组的序列容器。
  2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
  5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
  6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。

使用STL的三个境界:能用,明理,能扩展 ,那么下面学习vector,我们也是按照这个方法去学习


二、vector的模拟实现


1、模拟实现

#include<iostream>
#include<string>
#include<assert.h>
using namespace std;
namespace zsc
{
  template<class T>
  class vector
  {
  public:
    typedef T* iterator;
    typedef const T* const_iterator;
    iterator begin()
    {
      return _start;
    }
    iterator end()
    {
      return _finsh;
    }
    const_iterator begin() const
    {
      return _start;
    }
    const_iterator end() const 
    {
      return _finsh;
    }
    template<class InputIterator>
    vector(InputIterator frist, InputIterator last)
    {
      while (frist != last)
      {
        push_back(frist);
        frist++;
      }
    }
    vector(size_t n, const T& val = T())
    {
      reserve(n);
      for (size_t i = 0; i < n; i++)
      {
        push_back(val);
      }
    }
    vector(int n, const T& val = T())
    {
      reserve(n);
      for (size_t i = 0; i < n; i++)
      {
        push_back(val);
      }
    }
    void swap(vector<T>& v)
    {
      std::swap(_start, v._start);
      std::swap(_finsh, v._finsh);
      std::swap(_endofstorage, v._endofstorage);
    }
    vector<T>& operator=(vector<T> tmp)
    {
      swap(tmp);
      return *this;
    }
    size_t size()
    {
      return _finsh - _start;
    }
    size_t capacity()
    {
      return _endofstorage - _start;
    }
    vector()
    {}
    ~vector()
    {
      delete[] _start;
      _start = _finsh = _endofstorage = nullptr;
    }
    T& operator[](size_t pos)
    {
      assert(pos < size());
      return _start[pos];
    }
    void reserve(size_t n)
    {
      if (n > capacity())
      {
        T* tmp = new T[n];
        size_t sz = size();
        if (_start)
        {
          for (size_t i = 0; i < sz; i++)
          {
            tmp[i] = _start[i];
          }
          delete[] _start;
        }
        _start = tmp;
        _finsh = _start + sz;
        _endofstorage = _start + n;
      }
    }
    void resize(size_t n, const T& val = T())
    {
      if (n <= size())
      {
        _finsh = _start + n;
      }
      else
      {
        reserve(n);
        while (_finsh < _start + n)
        {
          *_finsh = val;
          ++_finsh;
        }
      }
    }
    void insert(iterator pos, const T& x)
    {
      assert(pos >= _start);
      assert(pos <= _finsh);
      if (_finsh == _endofstorage)
      {
        size_t len = pos - _start;
        reserve(capacity() == 0 ? 4 : capacity() * 2);
        pos = _start + len;
      }
      iterator end = _finsh - 1;
      while (end >= pos)
      {
        *(end + 1) = *(end);
        --end;
      }
      *pos = x;
      ++_finsh;
    }
    iterator erase(iterator pos)
    {
      assert(pos >= _start);
      assert(pos < _finsh);
      iterator it = pos + 1;
      while (it < _finsh)
      {
        *(it - 1) = *it;
        ++it;
      }
      --_finsh;
      return pos;
    }
    void push_back(const T& x)
    {
      if (_finsh == _endofstorage)
      {
        size_t sz = size();
        size_t cp = capacity() == 0 ? 4 : capacity() * 2;
        T* tmp = new T[cp];
        if (_start)
        {
          memcpy(tmp, _start, sizeof(T) * sz);
          delete[] _start;
        }
        _start = tmp;
        _finsh = _start + sz;
        _endofstorage = _start + cp;
      }
      *_finsh = x;
      ++_finsh;
    }
  private:
    iterator _start = nullptr;
    iterator _finsh = nullptr;
    iterator _endofstorage = nullptr;
  };
  void test1()
  {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);
    cout << "push_back and pop_back :";
    for (auto i : v)
      cout << i << " ";
    cout << endl;
    v.insert(v.begin() + 2, 30);
    cout << "insert:";
    for (auto x : v)
      cout << x << " ";
    cout << endl;
    v.erase(v.end() - 1);
    cout << "erase:";
    for (auto x : v)
      cout << x << " ";
    cout << endl;
    v.reserve(20);
    cout << "reserve(20): size:" << v.size() << " capacity:" << v.capacity() << endl;
    v.resize(100);
    cout << "resize(100): size:" << v.size() << " capacity:" << v.capacity() << endl;
  }
}
int main()
{
  zsc::test1();
  return 0;
}


2、测试结果

8a378d29491e4d16b6818f70b7ce6cf0.png

目录
相关文章
|
2月前
|
存储 编译器 C++
【C++】vector介绍+模拟实现
【C++】vector介绍+模拟实现
|
3月前
|
C++ 容器
C++中向量的操作vector
C++中向量的操作vector
|
2月前
|
算法 编译器 Linux
【C++】vector的模拟实现
【C++】vector的模拟实现
|
2月前
|
存储 算法 C语言
【C++】vector的认识与使用
【C++】vector的认识与使用
|
2月前
|
存储 算法 C++
【C++】vector介绍以及模拟实现(超级详细)
【C++】vector介绍以及模拟实现(超级详细)
47 4
|
2月前
|
C++ 索引
C++数组、vector求最大值最小值及其下标
C++数组、vector求最大值最小值及其下标
60 0
|
3月前
|
存储 C语言 C++
【C++】vector的使用上
**C++ STL的vector简介与用法:** Vector是动态顺序数组,提供高效下标访问,支持动态增长。与数组类似但可自动调整大小。常用构造函数包括默认、填充、迭代器范围和拷贝构造。析构函数自动释放内存。赋值运算符执行深拷贝。迭代器接口包括`begin()`和`end()`(反向对应`rbegin()`和`rend()`),C++11增加了const版本以支持只读访问。示例代码展示了不同构造函数和迭代器的使用。
|
4月前
|
C++ 容器
C++之评委打分案例(vector与deque容器练习)
C++之评委打分案例(vector与deque容器练习)
|
4月前
|
存储 编译器 C++
【C++ 初阶路】--- 类和对象(下)
【C++ 初阶路】--- 类和对象(下)
18 1
|
4月前
|
存储 编译器 C语言
【C++初阶路】--- 类和对象(中)
【C++初阶路】--- 类和对象(中)
25 1