zoukankan      html  css  js  c++  java
  • STL浅析——序列式容器vector的数据结构

      vecotr 一词原来的意思是:矢量,向量,航向,顾名思义指的就是类似于数组的一个存储数据的序列,因此所采用的数据结构非常简单:连续的线性空间,它以两个迭代器 _M_start 和 _M_finish 分别指向配置得来的连续线性空间中目前已被使用的范围,并以迭代器 _M_end_of_storage 指向整块连续空间的尾端:

    template <class _Tp, class _Alloc> 
    class _Vector_base {
    public:
      typedef _Alloc allocator_type;
      allocator_type get_allocator() const { return allocator_type(); }
    
      _Vector_base(const _Alloc&)
        : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
      _Vector_base(size_t __n, const _Alloc&)
        : _M_start(0), _M_finish(0), _M_end_of_storage(0) 
      {
        _M_start = _M_allocate(__n);
        _M_finish = _M_start;
        _M_end_of_storage = _M_start + __n;
      }
    
      ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
    
    protected:
      _Tp* _M_start;
      _Tp* _M_finish;
      _Tp* _M_end_of_storage;
    
    };
    
    #endif /* __STL_USE_STD_ALLOCATORS */
    
    template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
    class vector : protected _Vector_base<_Tp, _Alloc> 
    {
    private:
      typedef _Vector_base<_Tp, _Alloc> _Base;
    
    protected:
    #ifdef __STL_HAS_NAMESPACES
      using _Base::_M_allocate;
      using _Base::_M_deallocate;
      using _Base::_M_start;
      using _Base::_M_finish;
      using _Base::_M_end_of_storage;
    #endif /* __STL_HAS_NAMESPACES */
    };

      为了降低空间配置时的速度成本,vector 实际配置的大小可能比客户端需求量更大,以备将来可能的扩充,这便是容量(capacity)的概念,当容器满载的时候,整个 vector 就必须另外寻找内存存数据。

      使用_M_start,_M_end,_M_end_of_storage三个迭代器,便能轻易地提供首尾标识、大小、容量、空容器判断,标注运算子、最前端元素值,最后端元素值等功能。

      

    template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
    class vector : protected _Vector_base<_Tp, _Alloc> 
    {
    
    ...
    public:
      iterator begin() { return _M_start; }
      const_iterator begin() const { return _M_start; }
      iterator end() { return _M_finish; }
      const_iterator end() const { return _M_finish; }
    
      reverse_iterator rbegin()
        { return reverse_iterator(end()); }
      const_reverse_iterator rbegin() const
        { return const_reverse_iterator(end()); }
      reverse_iterator rend()
        { return reverse_iterator(begin()); }
      const_reverse_iterator rend() const
        { return const_reverse_iterator(begin()); }
    
      size_type size() const
        { return size_type(end() - begin()); }
      size_type max_size() const
        { return size_type(-1) / sizeof(_Tp); }
      size_type capacity() const
        { return size_type(_M_end_of_storage - begin()); }
      bool empty() const
        { return begin() == end(); }
    
      reference operator[](size_type __n) { return *(begin() + __n); }
      const_reference operator[](size_type __n) const { return *(begin() + __n); }
    ...
      reference front() { return *begin(); }
      const_reference front() const { return *begin(); }
      reference back() { return *(end() - 1); }
      const_reference back() const { return *(end() - 1); }
    ... };

      如下为vector示意图:

    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    人与人之间的本质
    如何让百度搜索不到
    js.prototype最深刻的理解
    调用函数不能用&
    浏览器的缓存就是关闭了浏览器任然存在
    Spring switch的使用
    thymeleaf如何遍历数据 each循环的使用
    spring 机制 扫描包
    Spring分层次建包
    如何使用thymeleaf显示控制传递过来的数据
  • 原文地址:https://www.cnblogs.com/Forever-Road/p/6831336.html
Copyright © 2011-2022 走看看