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

目录
相关文章
|
4月前
|
存储 编译器 C++
【C++】vector介绍+模拟实现
【C++】vector介绍+模拟实现
|
14天前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
40 4
|
2月前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
23 1
|
2月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
65 6
|
2月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化1
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
69 7
|
2月前
|
编译器 C++
【C++】—— vector模拟实现
【C++】—— vector模拟实现
|
2月前
|
编译器 C语言 C++
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
52 3
|
2月前
|
C++
【C++】C++ STL探索:Vector使用与背后底层逻辑(三)
【C++】C++ STL探索:Vector使用与背后底层逻辑
|
2月前
|
编译器 Linux C++
【C++】C++ STL探索:Vector使用与背后底层逻辑(二)
【C++】C++ STL探索:Vector使用与背后底层逻辑
|
2月前
|
编译器 C++ 容器
【C++】C++ STL探索:Vector使用与背后底层逻辑(一)
【C++】C++ STL探索:Vector使用与背后底层逻辑