读完侯捷先生的《STL源码剖析》,感觉真如他本人所说的“庖丁解牛,恢恢乎游刃有余”,STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵~

纵观全书,讲得最多、最透彻的就是C++的Generic Programming的思想。STL通过class template,function template将容器、迭代器、算法从数据类型中解脱出来,使其能“以不变应万变”,并能针对不同数据类型的相关特性(type_traits),从各种版本的实现中选最优而用之,从具体到抽象,又兼具具体特性的考虑,实乃智慧的结晶。这本书也开阔了我的眼界,使我见识了如partial specialization(偏特化),Specialization and Generalization,以偏特化的方式使C++具备type of的能力等的语言运用的现象。下面就先来讲一下class template partial specialization(类模板偏特化):

  • 1. 偏特化

所谓偏特化就是我们在设计class template的时候,除了提供必要的一般化设计之外,还设计了其它比较特殊的版本(比如接受T*为参数等等)。这些版本跟一般化的版本相比,要特殊一些,但有没有丢失什么类型都要的一般性,所以称之为部分特殊化或者偏特化。我们在实例化一个class template的时候,C++会根据传入的template参数类型,自动选取匹配程度最高的template进行实例化,举个栗子:

// 一般化设计

template <class I, class O>

struct testClass

{

testClass() { cout << "I, O" << endl; }

};

// 偏特化版本1

template <class T>

struct testClass< T*, T*>

{

testClass() { cout << "T*, T* " << endl; }

};

// 偏特化版本2

template <class T>

struct testClass<const T*, T*>

{

testClass() { cout << "const T*, T* "<<endl; }

};

int main()

{

testClass<int, char> obj1; // I, O

testClass<int*, int*> obj2; // T*, T*

testClass<const int*, int*> obj3; // const T*, T*

}

  • 2. STL的内存管理

STL的容器要装元素,必须要有空间,而空间从哪里来,从空间配置器allocator中来。

为了减少内存碎片的产生以及提高效率,STL采用两级的空间配置器。有图有真相:

其中,如果需求区块大于128 bytes,则用的是第一级配置器;否则使用第二级配置器,STL一般都默认使用第二级配置器。

先讲第一级配置器:

STL中分配内存和初始化对象时分开进行的。对象的构造construct()比较简单,直接用placement new(用于在已经分配好的空间中构造对象),调用该类型的构造函数就好了。而析构destroy()因为涉及到该类型是不是含trivial destructor,因而有些小复杂。所谓trivial destructor就是那些无关痛痒的dtor(例如,函数体为空),当我们知道含有trivial dtor,我们在析构的时候就可以不调用那些trivial dtors(因为无关痛痒嘛~),从而降低函数调用的成本。相反,若不含trivial dtors(例如涉及到new-delete的动态内存分配),我们在析构的时候就要老老实实调用dtor,否则会memory leak哦~废话少说,上图:

第一级配置器用到了一个内存不足处理例程,即当遇到内存不足,无法分配的时候,就调用这个处理例程。这个处理例程可能会释放一些内存,然后继续尝试分配。这个类似于C++的new-handler机制。

然后是第二级配置器。第二级配置器采用一个freelists的自由链表来管理空闲的区块,有16条不同大小的区块链表,大小从8,16,24...到128 bytes。目的是避免太多的小区快造成内存碎片,同时减少配置时的overhead。例如cookie(你在new一个对象的空间时,系统可能会分配比sizeof(你的对象)略大的内存空间,多出了空间用来记录内存大小,这样delete []p的时候就知道该free多少内存空间了~)。使用第二级配置器分配空间时,如果能从freelists中找到满足需求的最小区块,则从freelists中拨一个区块出去,在deallocate的时候再回收这个区块。当freelists中所需大小的区块已经一个不剩了(该大小的区块链表为null),则调用refill,从memory pool(内存池)中获取一整块大内存,再切分为所需大小的区块,链接到该链表,为该大小的区块“补仓”。如果memory pool也“没货”了,则唯有向heap要了。如果heap有,则向memory pool“注水”;如果heap也没有,则会调用第一级配置器,那里有个内存不足处理例程,实在不行会抛出个exception什么的。再见图:

另外,除了construct()和destroy()以外,还有三个有用的作用于未初始化内存的函数:

好了,今天先讲这么多,碎觉去~~~

(原创滴~)STL源码剖析读书总结1——GP和内存管理的更多相关文章

  1. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  2. STL源码剖析读书笔记--第四章--序列式容器

    1.什么是序列式容器?什么是关联式容器? 书上给出的解释是,序列式容器中的元素是可序的(可理解为可以按序索引,不管这个索引是像数组一样的随机索引,还是像链表一样的顺序索引),但是元素值在索引顺序的方向 ...

  3. Stl源码剖析读书笔记之Alloc细节

    阅读基础: Foo *pf = new Foo; 执行了两个步骤: 1)::operator new 向系统申请内存. 2) 调用Foo::Foo()构造函数构造实例.  ==> 申请内存,构造 ...

  4. STL源码剖析读书笔记--第6章&第7章--算法与仿函数

    老实说,这两章内容还蛮多的,但是其实在应用中一点点了解比较好.所以我决定这两张在以后使用过程中零零散散地总结,这个时候就说些基本概念好了.实际上,这两个STL组件都及其重要,我不详述一方面是自己偷懒, ...

  5. 《STL源码剖析》读书笔记

    转载:https://www.cnblogs.com/xiaoyi115/p/3721922.html 直接逼入正题. Standard Template Library简称STL.STL可分为容器( ...

  6. 通读《STL源码剖析》之后的一点读书笔记

    直接逼入正题. Standard Template Library简称STL.STL可分为容器(containers).迭代器(iterators).空间配置器(allocator).配接器(adap ...

  7. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  8. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  9. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

随机推荐

  1. 享元模式(咖啡屋)【java与模式】

    package com.javapatterns.flyweight.coffeeshop; public class Flavor extends Order { private String fl ...

  2. 如何讓Android系統顯示CJK擴展區漢字

    由於一些特殊需要,需要在個人設備上顯示CJK擴展區漢字,經多方詢問並驗證,找到了一下辦法,暫總結如下. 一.電腦上顯示 在電腦(Windows,Linux,Mac等系統)上可以通過安裝「花園明朝字體」 ...

  3. rapidxml对unicode的支持

    为了提高duilib创建布局控件的效率,在LuaDui项目中使用rapidxml解析器替换了duilib库自带的xml解析器. duilib使用unicode编译,所以rapidxml需要解析unic ...

  4. leetcode problem (2-4)

    Problem 2 --- Add Two Numbers 简单的模拟题. Problem 3 --- Longest Substring Without Repeating Characters 题 ...

  5. PHPUML 生成UML

    Selecting the UML/XMI version To select which version of the UML/XMI standards you want your XMI to ...

  6. Python3 列表

    list是一种有序的集合,可以随时添加和删除其中的元素. >>> classmates = ['Michael', 'Bob', 'Tracy'] >>> clas ...

  7. sqlserver批量插入数据问题

    下午做一个批量添加的功能,自动添加的那种,总是没有达到理想情况,后来请教师傅,给了这个批量添加的代码,一改果然好了,敬佩之情油然而生哈.分享下~ insert into t_ShopApplicati ...

  8. 在ECSHOP首页今日特价(促销商品)增加倒计时效果

    看到不少朋友在找首页特价商品倒计时的修改方法,写了这篇文章希望能帮到有此需要的朋友们 1.首先修改程序部分 打开includes/lib_goods.php 找到get_promote_goods() ...

  9. [python]filter

  10. C# net部署图片分布式存储服务器的小案例

    如果web服务用户多了,访问多了,用户上传的图片,文件等内容放在一块,想必服务器是承受不住的,这个时候,我们就需要考虑分布式存储的方法了. 如图所示:一个web服务器拖2个图片服务器 如何做到用户上传 ...