本节主要总结模板及其类模板分类以及STL里面的分配器、容器内部结构以及容器之间的关系和分类,还介绍了容器中List的结构分布

1、源代码版本介绍

  1.1 VC的编译器源码目录:

2、类模板

  2.1 类模板简介:

  2.2 类模板分类:

  泛化(GP  Generic Programming),特化(Specialization),二者区别在于特化版本相比泛化版本可能存在效率上的优化

  2.3 偏特化(局部特化 Partial Specialization)

    • 特化又叫做全部特化,上面的例子中类模板参数只有一个,其实可以由多个,这个全部特化就是对所有的参数都进行特殊绑定;
    • 偏特化叫做局部特化,下面例子对于多个参数只绑定其中一部分(局部数量或者局部范围内的绑定)。

  

3、函数模板

  3.1 函数模板简介:

4、 分配器

4.1 分配内存实质

  1. 分配器是容器的幕后英雄,负责内存的使用,但是不建议用户直接使用它,因为没有需要用它,它是专门为容器服务的,了解分配器可以更好的掌握容器的操作效率,方便我们挑选合适的容器;
  2. 分配器操作内存的实质还是调用C Runtime Library的malloc和free(可以说c++的new以及任何其他上层操作内存的方式最终一层层调用都是回归到malloc和free这两个函数上),这两个函数再根据不同平台再去调用各自的System API。
  3. 系统申请的内存如下

  所以每次申请的内存后系统分配给我们的远远大于我们实际申请的空间,因为系统要给这块内存附加一定的标识(也可叫做cooking或者额外开销),以方便释放操作,因为附加的部分是固定的,也就说我们申请的内存越大,附加部分占用的比重就越小。

4.2 分配器源码实现

注意:如果我们每次放入容器的元素太小,比如放一个long(4个字节),那内存产生的额外的开销将会很大,如果放入100万个,那额外开销可能比你放的100万个long还要多,内存消耗将会很可怕的。

4.3 分配器的使用

  由此可见,分配器的使用在释放时需要我们自己去记得当初申请了多少内存,显然是不方便的,但是我们在使用容器时不用关心,结论就是个人慎用。

4.4 分配器工作模式

  用分配器而不直接用C RunTime Library提供的malloc函数,其本质上是减少内存的额外开销,也就是说分配器会预先开好一定的空间,尽量减少malloc的使用次数,它不是需要多少开多少,也就是我们常说的内存池设计。

5、 容器的结构分类介绍

5.1 各个容器的结构关系

容器间的关系,以及各个容器所占用的字节大小如下所示

5.2 List结构分析

5.2.1 基本结构

  G2.9版本,list的设计是双向环状链表,每个节点是一个指针,这个节点又由两个指针(一个向前指一个向后指)和数据部分data组成;

  list整体数据部分是node,而node是list_node*类型,list_node是list的一个节点,所以list占用的内存大小是4(在32位机器上),当list从allocate拿内存时是以节点为单位的,也就是说除了数据data部分,还要有两个指针;

5.2.2 迭代器操作方式

  迭代器的操作要回到节点内部,而不是直接跳到下一个地址,比如迭代器++操作,就是要回到节点内部找到next指针指到的位置,然后再去挪动迭代器,迭代器的操作,都是一堆运算符重载

注意:c++语法不允许后++加两次,因为后加加操作符重载后返回的不是引用(后加加里面有临时变量)

5.2.3 多版本对比介绍

注意:最新版本中,list数据部分(node节点)拆成了两个指针,list大小为两个指针的大小,为8(32位系统下)

 

C++标准库分析总结(二)——<模板,分配器,List>的更多相关文章

  1. 怎么使用C++标准库来实现二维数组

    在编程里,像界面布局是二维的,那么常常使用二维数组来表示界面的元素,那么就需要使用二维的数组,在现在C++肯定是以标准库为基础了,不再使用C的二维数组,那么怎么样做呢?下面就使用vector来实现二维 ...

  2. C++标准库分析总结(三)——<迭代器设计原则>

    本节主要总结迭代器的设计原则,以及iterstor traits的设计作用 1.迭代器遵循的原则 迭代器是算法和容器的桥梁,它是类模板的设计,迭代器必须有能力回答算法提出的问题才能去搭配该算法的使用 ...

  3. C++标准库分析总结(一)

    之前学习过标准库,最近身边有人问到相关话题,故在此做一个总结 1 标准库介绍 C++标准库:C++ Standard Library C++标准模板库:Standard Template Librar ...

  4. C++标准库分析总结(八)——<仿函数、适配器、istream_iterator、ostream_iterator、bind>

    一.仿函数定义 仿函数是STL中最简单的部分,存在的本质就是为STL算法部分服务的,一般不单独使用.仿函数(functors)又称为函数对象(function objects),虽然函数指针虽然也可以 ...

  5. C++标准库分析总结(五)——<Deque、Queue、Stack设计原则>

    本节主要总结标准库Deque的设计方法和特性以及相关迭代器内部特征 1.Deque基本结构 Deque(双向队列)也号称连续空间(其实是给使用者一个善意的谎言,只是为了好用),其实它使用分段拼接起来的 ...

  6. C++标准库分析总结(四)——<Vector、Array、Forward_list设计原则>

    本节主要总结标准库Vector和Array的设计方法和特性以及相关迭代器内部特征 1.Vector 1.1 Vector 内部实现 Vector是自增长的数组,其实在标准库中没有任何一种容器能原地扩充 ...

  7. golang标准库分析之net/rpc

    net/rpc是golang提供的一个实现rpc的标准库.

  8. C++标准库分析总结(九)——<HashFunction、Tuple>

    一.HashFunction 当我们在使用hash table以及由它做底层的数据结构时,我们必不可少要讨论hash function,所谓的哈希函数就是产生一个数,这个数越乱越好,以至于达到避免碰撞 ...

  9. PIL:Python Imaging Library(图像处理标准库)和Qrcode:二维码生成

    安装PIL Mac或Linux安装命令:sudo easy_install PIL 如果报错:fatal error: 'freetype/fterrors.h' file not found Mac ...

随机推荐

  1. C#在txt类文件中追加内容

    string path = "test.txt"; FileStream mystream = new FileStream(path, FileMode.OpenOrCreate ...

  2. CVE-2019-11517 CSRF in Wampserver 3.1.4-3.1.8

    https://www.cnblogs.com/iAmSoScArEd/ Affected product:WampServer 3.1.4-3.1.8 Offiical description:&q ...

  3. pycharm连接数据库

    今天说说如何使用pycharm连接oracle数据库 1.首先你需要安装oracle数据库 2.在pycharm中安装cx_Oracle.在file->settings->Project- ...

  4. Keras Conv1d 参数及输入输出详解

    Conv1d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True) filter ...

  5. 缺包与maven

    一. 缺包 1. 打开pom.xml 将依赖加入. 2. mvn clean install -DskipTests 3. scp target/lib/****.jar(刚刚的依赖的架包) 服务器地 ...

  6. SATB深入详解与问题剖析【纯理论】

    延着上一次[https://www.cnblogs.com/webor2006/p/11147893.html]的理论继续. SATB: 在G1中,使用的是SATB(Snapshot-At-The-B ...

  7. python-selenium安装笔记

    python-selenium操作火狐,谷歌,360,ie 亲测可用,windows环境 python3.6 由于python2到2020年不进行维护所有都用python3 selenium pip ...

  8. CORS通信

    CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨域的服务器,发出XMLHttpRequest请 ...

  9. Gitlab,Git设置及使用前的准备

    1. git config --global user.name "……" #定义全局的用户名 git config --global user.email "……&qu ...

  10. (C99)复合字面量

    #include <stdio.h> struct argvs { char a[64]; int b; }; int pfunc(struct argvs *a) { printf(&q ...