SGISTL源码探究-vector容器(下)

SGI STL原代码分析之Vector(一)。 STL版本有很多种,STL是一套泛型编程框架标准,只要实现了这套标准的东西,都是叫做STL。。  所以STL有很多版本, 但是SGI STL是最为标准,而且是STL之父写的所以是最为权威的STL模板。 目的:分析Vector构造到Push_back这一系列过程中,STL中的实现过程。 开干。。。~!!!! 首先来到Vector这个类,Vector模板里面传递了两个参数,第一个是 阅读详情

前言

在本小节中,我们将接着上一下节,继续分析关于vector的内存控制,及一些常用操作部分。

vector的内存控制

引入

在上一节中我们给出了一个简单的例子,借助这个例子已经大约明白了vector管理内存的机制。接下来,我们就来看看push_back这些操作。

push_back
void push_back(const T& x) {
  /* 判断是否到vector最大容量
   * 若没有,则构造该对象
   * 若达到了,则调用`insert_aux`函数
   */
  if (finish != end_of_storage) {
    construct(finish, x);
    ++finish;
  }
  else
    insert_aux(end(), x);
}

事实上,发生容量增倍的操作在insert_aux中。

insert_aux
template <class T, class Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
  /* 若还有空间可用,则直接使用
   * 如果没有,则扩充空间
   */
  if (finish != end_of_storage) {
    //构造一个新的元素,并以vector最后一个元素作为初值
    //finish迭代器指向的位置是没有元素的
    //不要忘了[first, finish),在容器中都是这样
    construct(finish, *(finish - 1));
    ++finish;
    T x_copy = x;
    /* 这步操作实现的是将[position, finish -2)的元素从尾到头复制到从finish-1-1指向的位置(依次向后移)
     * 比如 1 2 3 4 5 5
     * 结果就是 1 2 2 3 4 5
     * 然后再将position指向的位置赋成x
     */
    copy_backward(position, finish - 2, finish - 1);
    //赋值
    *position = x_copy;
  }
  else {
    /*进行到这里,代表容量不够了 进行扩容 */
    //此时的size()大小应该与capacity()大小相等
    const size_type old_size = size();
    /* 这里考虑到了vector容量为0的情况
     * 若不为0,则扩充为原来的2倍
     */
    const size_type len = old_size != 0 ? 2 * old_size : 1;
    /* 注意vector并不是在原空间的基础上进行扩充
     * 而是调用空间配置器另外申请一块新的空间
     * 这是为了防止原有空间无法提供这么大的空间
     */
    iterator new_start = data_allocator::allocate(len);
    iterator new_finish = new_start;
    __STL_TRY {
      //将原vector的元素拷贝到新的vector中
      new_finish = uninitialized_copy(start, position, new_start);
      //在新的vector中插入x
      construct(new_finish, x);
      ++new_finish;
      //将插入点position之后元素也拷贝过来
      new_finish = uninitialized_copy(position, finish, new_finish);
    }


#       ifdef  __STL_USE_EXCEPTIONS
    catch(...) {
      //以下是异常情况
      //若发生异常,则销毁拷贝过去的元素
      //最后将申请的空间释放
      destroy(new_start, new_finish);
      data_allocator::deallocate(new_start, len);
      throw;
    }
#       endif /* __STL_USE_EXCEPTIONS */
    /* 一切大功告成之后,将原空间进行销毁
     * 并把start、finish、end_of_storage这几个迭代器指向新的空间
     */
    destroy(begin(), end());
    deallocate();
    start = new_start;
    finish = new_finish;
    end_of_storage = new_start + len;
  }
}

可能你还有一些疑问,那就是为什么insert_aux中,当有容量可用时,为什么不像push_back那样直接构造元素,而要调用copy_backward。这是因为,insert_aux也可能会被insert调用,而insert是指定位置进行插入的。
并且当空间分配成功后,拷贝旧空间的元素时,也要将position之后的元素拷贝到新空间中,这对于push_back操作其实是不必要的,但是同样,insert操作可能会遇到这种情况。

接下来,我们再看一看vector的insert操作(STL规定插入操作是插入到position的前一个位置)

insert

insert函数其实有众多的重载版本,大致分为:

  • 指定位置插入一个元素
  • 指定位置插入多个元素
  • 以迭代器的范围插入
//指定位置插入x
iterator insert(iterator position, const T& x) {
  size_type n = position - begin();
  if (finish != end_of_storage && position == end()) {
    construct(finish, x);
    ++finish;
  }
  else
    insert_aux(position, x);
  return begin() + n;
}
iterator insert(iterator position) { return insert(position, T()); }
//迭代器范围插入
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
  range_insert(position, first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator position,
            const_iterator first, const_iterator last);
#endif /* __STL_MEMBER_TEMPLATES */
//在pos前插入n个x
void insert (iterator pos, size_type n, const T& x);
void insert (iterator pos, int n, const T& x) {
  insert(pos, (size_type) n, x);
}
void insert (iterator pos, long n, const T& x) {
  insert(pos, (size_type) n, x);
}

接下来,我们来分析这三种情况:

1. 指定位置插入
iterator insert(iterator position, const T& x) {
  size_type n = position - begin();
  /* 如果此时有足够的空间并且插入的元素在末端
   * 就直接在末端插入新元素
   * 如果没有足够空间或插入的元素不在尾部
   * 则调用insert_aux进行插入(插入的元素不在尾部会走if分支,容量不够走else分支)
   */
  if (finish != end_of_storage && position == end()) {
    construct(finish, x);
    ++finish;
  }
  else
    insert_aux(position, x);
  //返回指向插入元素的迭代器
  return begin() + n;
}
2. 范围插入

根据条件编译分不同的函数,但是实现都是一样的,range_insert和下面这个insert的代码一致,就拿其中一个分析就行了。

template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position,
                              const_iterator first,
                              const_iterator last) {
  if (first != last) {
    size_type n = 0;
    //计算出两个迭代器之间的距离(即元素个数)
    distance(first, last, n);
    //容量够用的情况
    if (size_type(end_of_storage - finish) >= n) {
      const size_type elems_after = finish - position;
      iterator old_finish = finish;
      /* 若插入点之后的元素个数大于新增元素个数
       * 那么我们就可以腾出n个位置给新增元素
       * 如果插入点之后的元素个数小于新增元素个数
       * 则先将[first + elems_after, last)的元素拷到finish之后
       * 然后将[position, old_finish)的元素拷贝到finish之后,腾出elems_after个位置
       * 最后将[first, first + elems_after)的元素拷贝到腾出的位置中
       */
      if (elems_after > n) {
        //将[finish-n, finish)范围内的元素移动到finish之后
        //目的在于腾出n个位置给新元素
        uninitialized_copy(finish - n, finish, finish);
        finish += n;
        //将[position, old_finish - n)的元素依次后移
        copy_backward(position, old_finish - n, old_finish);
        //将[first, last)拷贝进position指向的位置
        copy(first, last, position);
      }
      else {
        //这个插入操作其实是分了两部分的
        //其中一部分是将[first+elems_after, last)的元素拷贝到finish之后,尾部假定为new_finish
        //而[first, first+elems_after)这一部分则先让原来的元素腾到new_finish之后,再复制到腾出的地方
        uninitialized_copy(first + elems_after, last, finish);
        finish += n - elems_after;
        uninitialized_copy(position, old_finish, finish);
        finish += elems_after;
        copy(first, first + elems_after, position);
      }
    }
    else {
      //以下是空间不足需要重新分配的情况
      const size_type old_size = size();
      const size_type
      //此时并没有直接分配old_size的两倍
      //这是考虑到分了old_size的两倍之后,n过于大,容量还是不够的情况
      //所以取两者的最大值
      //再不济,也要把插入n个元素装下
      len = old_size + max(old_size, n);
      iterator new_start = data_allocator::allocate(len);
      iterator new_finish = new_start;
      __STL_TRY {
        /* 因为是插入到position之前
         * 所以需要分成三部将元素拷贝到新空间中
         * 第一部分:[start, position)
         * 第二部分:[first, last)
         * 第三部分:[position, finish)
         */
        new_finish = uninitialized_copy(start, position, new_start);
        new_finish = uninitialized_copy(first, last, new_finish);
        new_finish = uninitialized_copy(position, finish, new_finish);
      }
#         ifdef __STL_USE_EXCEPTIONS
      catch(...) {
      //异常处理
      destroy(new_start, new_finish);
      data_allocator::deallocate(new_start, len);
      throw;
      }
#         endif /* __STL_USE_EXCEPTIONS */
      //释放原空间,并调整迭代器
      destroy(start, finish);
      deallocate();
      start = new_start;
      finish = new_finish;
      end_of_storage = new_start + len;
    }
  }
}

容量够用的情况中又分成的elems_after > n或者elems_after < n这两种情况可能有点不好理解,最好自己画一下图有助于理解。

3. 插入n个元素

根据了n的类型不同进行了重载,不过最后都将n强转成size_type类型进行处理。
该函数和迭代器范围插入很相似,代码的逻辑几乎一模一样,除了迭代器范围插入时,插入新元素是调用copy拷贝,而插入n个元素这类是调用fill之外,并没有什么不一样,这里就不再贴代码占篇幅了。

clear

vector中的clear函数并不负责回收vector的空间,而是负责销毁vector所存的元素。
它的源码如下:

void clear() { erase(begin(), end());}

其实就是调用了erase函数。那我们接着来看erase函数。它有重载的版本。

//删除position迭代器指向的元素
iterator erase(iterator position) {
  /* 若position指向的不是最后一个元素
   * 那么直接将后面的元素向前移动就完事
   * 如果是最后一个,那就更简单了,直接将finish指向该元素,然后删除
   */
  if (position + 1 != end())
    copy(position + 1, finish, position);
  --finish;
  destroy(finish);
  return position;
}
//删除[first, last)范围内的元素
iterator erase(iterator first, iterator last)
{
  //将last之后的元素拷贝到first的位置,覆盖需要删除的元素
  iterator i = copy(last, finish, first);
  //当last-first的值(需要删除的元素个数)大于finish-last的值时,需要删除的元素没有被覆盖完,则调用destroy进行析构
  destroy(i, finish);
  //调整finish
  finish = finish - (last - first);
  return first;
}

其他操作

关于vector的操作确实挺多,以上也只列举了一些比较重要的。
下面我们再看几个操作符重载的函数以及reserve和resize函数。

重载[]
reference operator[](size_type n) { return *(begin() + n); }
重载==
template <class T, class Alloc>
inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}

可以看到两个vector容器是否相等需要满足两个条件:

  1. 元素个数相等
  2. 元素的值相等
重载=
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
  //如果自己对自己赋值,那直接返回就行了
  if (&x != this) {
    /* 判断自身的容量大小是否能存入x
     * 如果不能,分配一个跟x大小相同的空间,并将x拷贝进去
     * 然后销毁原空间
     * 再把迭代器指向新的空间
     */
    if (x.size() > capacity()) {
      iterator tmp = allocate_and_copy(x.end() - x.begin(),
                                       x.begin(), x.end());
      destroy(start, finish);
      deallocate();
      start = tmp;
      end_of_storage = start + (x.end() - x.begin());
    }
    /* 现有元素足够容下x
     * 直接将x的元素拷贝过来
     * 将没有被覆盖的元素析构掉
     */
    else if (size() >= x.size()) {
      iterator i = copy(x.begin(), x.end(), begin());
      destroy(i, finish);
    }
    /* 这种情况是现有元素的个数容不小x
     * 但是总容量可以容下x
     * 所以就需要把现有的元素全部覆盖了,然后把x剩下的元素拷贝到未使用的空间中去
     */
    else {
      copy(x.begin(), x.begin() + size(), start);
      uninitialized_copy(x.begin() + size(), x.end(), finish);
    }
    //最后统一调整finish
    finish = start + x.size();
  }
  //返回赋值后的vector
  return *this;
}

重载赋值操作符可能要稍微麻烦一点,不过比起insert之类的还是比较简单了。
最后再介绍两个函数reserve、resize

reserve

该函数的作用是将总容量设置为n

void reserve(size_type n) {
  if (capacity() < n) {
    const size_type old_size = size();
    //分配n大小的空间,将原来的元素拷贝过去
    iterator tmp = allocate_and_copy(n, start, finish);
    //删除原空间的元素
    destroy(start, finish);
    //释放原空间
    deallocate();
    //调整迭代器
    start = tmp;
    finish = tmp + old_size;
    end_of_storage = start + n;
  }
}
resize

该函数的作用就是调整vector的大小。

void resize(size_type new_size, const T& x)
{
  /* 如果要求调整到的大小比原来的大小小
   * 则需要将超出的部分删掉
   * 否则将填入新的元素,初值为x
   */
  if(new_size < size())
    erase(begin() + new_size, end());
  else
    insert(end(), new_size - size(), x);
}

小结

在本小节中我们分析了push_back、insert及一些操作符还有reserve及resize等函数。还有一些其他的操作不需要一一列举,感兴趣的可以自己去看代码,没有特别的复杂的了。
还需要特别注意的一点就是关于迭代器的失效问题,如果vector扩容了,那么会导致原来的迭代器都会失效,了解了vector源码之后,对这些特性应该也能理解。
关于vector的分析就到此结束,相信你对vector的内部机制有了更深刻的了解。接下来是list容器。

SGI的STL源代码实现 SGI的STL源代码 包括文档和代码。 The Standard Template Library, or STL, is a C++ library of container classes, algorithms, and iterators; it provides many of the basic algorithms and data structures of computer science. The STL is a generic library, meaning that its components are heavily parameterized: almost every component in the STL is a template. You should make sure that you understand how templates work in C++ before you use the STL. 立即下载

相关推荐

Buck电路中自举电容串联小电阻的作用

在Buck电路中,自举电容(Cboot)驱动高边MOSFET时,因寄生电感和电容会形成LC谐振回路,导致SW节点高频振铃,引发EMI问题。串联小电阻(Rboot)可引入阻尼效应,抑制振铃、改善波形和EMI性能,但会略微增加开关损耗。设计时建议预留可调电阻位(2Ω~20Ω),根据实测结果平衡效率与系统稳定性,提升电源可靠性。这一措施是优化开关电源EMC的常见实践。

硬核科技 627

SGI STL顺序容器 vector

目录在SGI STL中,vector和array都是数组容器,两种操作非常相似。区别在于:array是静态空间,一旦配置就不能改变;vector是动态空间,随着新元素加入,内部机制或自行扩充空间以容纳新元素。vector维护的是一个连续线性空间,不论元素类型是什么,普通指针都可以作为vector的迭代器而满足所有必要条件,因为vector需要的操作:operator*,operator->,operatro++, operator--, operator+, operator-, operator+=, o

木牛的博客 340

从轻量化到高精度:3DXML 转 STP 的工程数据升级技术指南

本文详细解析了3DXML转STP格式的工程数据升级技术,对比了两种格式在轻量化和高精度方面的特性差异,并提供了CATIA、FreeCAD及Python编程等多种专业级转换方案。通过实际案例展示了如何确保转换过程中的数据精度,适用于CAD设计、精密制造等场景,帮助工程师实现工程数据的高效升级。

weixin_29201859的博客 215

SGI STL源码剖析——序列式容器(vector)

序列式容器vectorvector定义vector迭代器和数据结构vector构造和内存管理vector元素操作 vector定义 vector几乎是我们使用最多的容器了,比起原生数组的静态空间,vector使用更加灵活。我们首先来看vector的定义,然后了解其对内存的操作,结合前面学习的空间配置器和迭代器。 在看vector模板的定义之前,先看其基类定义, // vector 继承 _Vector_base template <class _Tp, class _Alloc> class

qq_31082639的博客 514

【WRF-Chem教程-附录B】使用 MOZART 与WRF-Chem

使用MOZART与WRF-Chem

WW、forever的博客 242

【系统架构设计师-2023年真题】综合知识-答案及详解

要实现多任务间的协同工作,操作系统必须提供任务间的通信手段。嵌入式操作系统一般都会提供多任务间通信的方法,其中()是任务间最直接、最明显的通信方法,也是访问共享的数据结构,即不同的任务都可以访问同一地址空间。()作为一种更高级的通信方式,能够在同一处理器的各个任务间传递任意长度(理论上只受物理内存和机器字长限制)的信息。(1)A. 共享内存 B. Socket C. 消息传递 D. 信号量(2)A. 共享内存 B. Socket C. 消息传递 D. 信号量【答案】A、C关于星型拓扑结构,下列说法正确的是(

数据知道的博客 1万+

SGI STL Insert方法追加分析

在上一篇的分析中, 我们看了Vector Insert方法,但是其中的copy_backward(__position, _M_finish - 2, _M_finish - 1);等算法因为没有做出详解,所以分析的不够透彻,接下来我们继续进行分析。if (_M_finish != _M_end_of_storage) { construct(_M_finish, *(_M_finish -

qq_21441793的博客 575

FastAPI 高级特性:同异步路由函数、依赖注入与后台任务

在现代 Web 开发中,高效的性能和简洁的代码结构是至关重要的。FastAPI 作为一个现代、快速(高性能)的 Web 框架,凭借其对异步编程的原生支持和直观的依赖注入系统,迅速成为开发者的热门选择。在本文中,将深入探讨 `FastAPI` 中的几个核心概念:同异步函数的区别、`Depends` 依赖以及后台任务。

qq_43629857的博客 203

stl_vector::insert_aux方法原理

stl_vector::insert_aux源码 template <class T, class Alloc> void vector<T, Alloc>::insert_aux(iterator position, const T& x) { if (finish != end_of_storage) {//如果还有备用空间 construct(finish, *(finish - 1));//在备用空间开头构造一个对象,以最后一个元素为对象内容

欢乐的企鹅博客 755

【人工智能】向量数据库全生命周期数据安全防护体系:破解向量化与检索双环节泄露风险

大模型时代,向量数据库已成为RAG(检索增强生成)架构、语义检索、多模态应用的核心基础设施,解决了大模型幻觉、长上下文窗口限制、私有知识落地等核心痛点。但行业普遍存在认知误区:将Embedding向量等同于“无害的语义压缩乱码”,忽视了向量数据原生的泄露风险。

奶爸的编程之路,也就一周冷个三天 160

股票价格预测的秘密武器:用C#实现蒙特卡洛路径模拟,轻松掌握市场波动规律!

摘要: 蒙特卡洛模拟是股票预测的有效工具,通过随机抽样模拟价格路径,克服传统技术分析的局限性。其核心模型是几何布朗运动(GBM),描述股价随机变化过程。C#实现的关键步骤包括:1)获取输入参数;2)生成随机数路径;3)分析结果。该方法不预测具体价格,而是提供可能的价格范围,帮助投资者评估风险。代码结构清晰,分为输入、模拟、分析和可视化四个模块,通过参数封装提高可读性,适用于不确定市场的概率预测。

墨夶的博客 602

SGISTL源码探究-vector容器(上)

前言vector容器应该算是最常用的容器之一了,它是序列式容器的一种,即元素可被排序。vector被称为动态数组,可以随着元素的加入,内部的大小自行扩充。可能你对vector的机制有所耳闻,比如每次扩充时,扩充当前容量的2倍等。接下来,我们就进入到它的源码来看看vector是如何实现的。我们将它分为四部分进行分析,vector的迭代器,vector的内存分配及构造,vector的内存控制以及一些常用

Move_now的博客 810

基于STM32设计的数字电子秤

当前项目是采用采用STM32+称重模块+OLED实现了简单的电子秤项目,称重模块上采用24位的ADC芯片,精度较高。实现了称重,校准、去皮等功能。

1万+

【C++】Vector的使用和源码解析

其实很早之前,我就有去看STL源码的想法了。只是一直没有一个好的机会。最久空闲时间比较多,也正是这样一个好机会去阅读源码。为了事半功倍,不走弯路,我在网上查了很多资料。目前来说,C++ STL的源码相关的中文书籍还停留在侯捷老师的2002年出版的STL源码剖析。虽然侯捷老师确实是非常厉害的,很有教学能力的一位C++老师,但是还是要提,在计算机技术日新月异的环境下,一本二十多年前的书籍确实已经有点落后了。

meeiuliuus的博客 1741

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SGISTL源码探究-大根堆heap

前言小根堆和大根堆的概念在数据结构都讲过,等下简单的过一下就行了。在SGISTL的实现中,它并不作为一种容器,而是一系列的算法,用于给priority_queue提供支持,使优先级队列能够体现其优先级。 在SGISTL实现heap中,采用的数据结构并不是使用二叉树实现,而是采用隐式表达,即使用数组表示一个堆。能用数组表示这是因为堆总是一棵完全二叉树(没有节点漏洞):即若设二叉树的高度为h,除第 h

Move_now的博客 874

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

SGISTL源码阅读十 Vector容器下

SGISTL源码阅读十 Vector容器下 前言 之前我们已经对vector进行了比较深入的学习,本文章继续讲解vector的其他相关操作 深入源码 pop_back void pop_back() { --finish; destroy(finish); } pop_back的作用是将最后一个元素清除。 erase erase操作只负责销毁元素,而不负责释放空间 ...

Lyn&Xx 208

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

SGISTL源码-容器 笔记

本文是在阅读SGI STL v3.3源码中,遇到的一些问题及有意思的点。本文建立在已经观看过侯捷老师STL源码剖析课程的基础上。是在阅读源码过程中,对其中的内容进行补充、修饰。

weixin_46065476的博客 596

SGISTL源码阅读八 Vector容器上

SGISTL源码阅读八 Vector容器上 Vector概述 array是静态的数组,一经定义大小不可改变,这对于未知数组大小的情况来说是非常不利的,如果没有vector我们只能猜测一个较大的值来初始化数组。这无疑对空间造成了很大程度上的浪费,而且如果初始值过小,就得必须自己重新定义一个更大的数组,并且将原来的数据拷贝一份,再释放掉原来的空间。 vector被称为动态数组。随着元素的加入,它的内部...

Lyn&Xx 310

SGISTL源码阅读九 Vector容器中

SGISTL源码阅读九 Vector容器中 前言 在上一篇文章中我们了解了Vector的基本结构、构造以及内存分配,但是对于Vector的动态性并未涉及。 接下来我们继续学习vector的一些相关操作,从中我们可以看到vector是如何进行内存控制的 深入源码 push_back void push_back(const T&amp;amp; x) { //判断vector的使用量是否达到最大值 ...

Lyn&Xx 246

❤️ 【STL 序列式容器】 vector 超硬核源码剖析 ❤️

目录前言第4章 序列式容器4.1 容器的概念与分类4.1.1 序列式容器4.2 vector4.2.1 vector概述4.2.2 vector定义摘要4.2.3 vector的迭代器4.2.4 vector的数据结构4.2.5 vector的构造与内存管理4.2.6 vector的元素操作 前言 国庆七天假宛如一天假,定睛一看又要上班… 国庆档电影院热闹了不少,《长津湖》真的值回票价,吴京真不错,意外的是易烊千玺竟然演出了小戏骨的感觉,整部电影很有感染力,点赞! 外滩一如既往的人山人海,不过每次抱着去看人

GOOD GOOD STUDY, DAY DAY UP 887

SGISTL源码探究-优先级队列

前言在上一小节中,我们分析了heap算法,其实是为了priority_queue优先级队列做准备,它也不是容器,而是配接器,因为它是通过vector来实现的,然后封装了一些vector提供的接口供自己使用而形成的。 优先级队列,即一种特殊的队列,但是它内部的元素没有按照传统队列的先进先出这种顺序排序,而是按照元素的权值进行排列,所以执行出队操作时,出队的是权值最大的元素。priority_queu

Move_now的博客 760

SGISTL源码阅读十七 stack(栈)

SGISTL源码阅读十七 stack(栈) 前言 前面我们已经学习了序列式容器vector,list和deque。 本次要进行分析的是stack,它是一种先进后出(First In Lat Out,FILO)数据结构,在学习数据结构的时候应该都接触过,在这里stack是一个配接器(adapter),它默认以deque容器作为它的底部结构实现。接下来我们深入源码进行学习。 配接器 具有这种“修改某...

Lyn&Xx 444

C++容器总结(一)

在模板类的定义中,template 的T表示占符位,本身没有实际意义,用T或者Type都可以。这里的T表代表了一个不确定的数据类型,可以为任意的数据类型,可以是int、double、char等,而具体是那个类型则是创建对象的时候指定。这样就可以达到模板类处理任何数据类型的目的,提高代码的复用率。在每一个成员函数的定义都包含“template ”和“MyTemplate”,表明这是一个模板类MyTemplate的成员函数。

jieer___的博客 467

STL源码剖析(vector)

在SGI STL中,vector使用的是连续的内存空间,迭代器使用普通指针来实现。 因为使用的是连续的内存空间,在vector容量不足的时候会直接分配一块新的内存,把原来的元素copy进去,回收原来的内存空间。 因此在vector扩容的时候,原来的所有迭代器都会失效。 vector的实现基本都是围绕这start、end、end_of_storage三个指针,首先先看看vector的基本...

weixin_30810583的博客 61

SGI STL源码之vector

1、简介 vector是序列式容器的一种,其存储方式类似于数组,分配给它的空间是一段连续的内存。与数组不同的是,vector是动态空间,随着元素的不断增加,它的内部机制会自动扩充空间以容纳新的元素,不用担心空间不足的情况。 2、源码剖析

heart_love的博客 718

STL源码剖析__vector

按书中给出的简化的代码编写的,省略了异常处理。 vs2012编译时候会报告警,是copy操作的越界告警,虽然没影响,估计要修改下编码方式来解决。 //自行加入reserve函数的实现   #ifndef vector_H_ #define vector_H_ #include "allocator.h" namespace SGISTL { template cla

yyrrbadboy2012的专栏 417
上一篇: SGISTL源码探究-vector容器(上)
下一篇: SGISTL源码探究-list容器(上)
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值