STL源码剖析学习-体系结构与内核分析-1

分配器(allocator)简说

这是malloc()调用操作系统的命令后所作的事情,size所括的空间是程序所申请的内存,其它的数据项统称为Over Head。其中最常用的是首尾两个红色的块,保存了这整个内存空间的大小,这也是free函数不需要告诉释放的内存的大小的原因,因为free会自动去寻找这个首尾空间。那么over head和所申请的数据内存占用的比例来看,如果数据内存比较小,那么over_head会占用较大的比例,这不是很好的行为。

STL源码剖析学习-体系结构与内核分析-1_第1张图片

容器的元素大小是一样的,无论数量的多少,所以容器中的每个元素不必记录每个元素的over-head;所以,容器的allocate似乎不需要这样申请,尽量减少malloc的次数。

GNU2.9版本的分配器 alloc, GNU4.9版本改为__pool_alloc, 内存池的设计。
设计16条链表,每个链表负责某一特定大小的区块,第0条链表负责8个字节大小,第7号链表负责64个字节大小,第15号链表负责16*8=128字节大小。容器需要分配内存的时候,就会像这个链表来索要;容器的大小会被调整成8的倍数,比如50个字节被调整到56个字节,56是第6号链表负责,如果该链表没有挂载内存块,则调用malloc向内存申请数据,然后将内存块切割后用链表挂起来;因此每一块内存没有over-head的东西;
STL源码剖析学习-体系结构与内核分析-1_第2张图片

容器(Container)的背后需要分配器(allocator)支持对内存的使用和操作,但写程序时最好不要直接使用分配器,直接使用容器或者New/delete即可。
下述是容器源码中隐藏使用的分配器代码,在使用容器的时候我们不需要显示调用分配器。通过源码也可以看出,在类模板中,分配器这个参数是缺省提供的。
STL源码剖析学习-体系结构与内核分析-1_第3张图片

下述分配器的源码应该是GNUC的编译版本,VC中不一定适用。
STL源码剖析学习-体系结构与内核分析-1_第4张图片

OOP(Object-Oriented programming) VS GP (Generic Programming)

面向对象程序设计的思想希望将数据的操作和方法绑定在一起;
STL源码剖析学习-体系结构与内核分析-1_第5张图片

STL的list不允许使用全局的sort函数,因为std::sort的源码中,所用到的迭代器需要是RandomAccessIterator,而list的迭代器不能够满足这个要求。因为list是靠指针连接不相连的内存空间,因此不能对list的迭代器进行随机访问。

而泛型编程希望将数据的操作和方法分开来,它们之间关联的纽带是 iterator迭代器(泛化指针)。
STL源码剖析学习-体系结构与内核分析-1_第6张图片
STL源码剖析学习-体系结构与内核分析-1_第7张图片

操作符重载和模板越熟悉越好

操作符重载的基本写法:
STL源码剖析学习-体系结构与内核分析-1_第8张图片
下图是STL的list迭代器的类,迭代器是一种泛化指针,因此迭代器的类一般要模仿指针的操作,因此需要把与指针相关的操作符进行重载。下图所示:重载了*、->、++。
STL源码剖析学习-体系结构与内核分析-1_第9张图片

类模板/模板类
STL源码剖析学习-体系结构与内核分析-1_第10张图片
template / typename 关键字表明这是一个泛化的数据类型,在使用这个类的时候要明确指明T的数据类型。
函数模板和操作符重载的一个例子: 定义了一个类stone,重载了<操作符。在调用模板函数min的时候,指明数据类型是stone对象,而min用到了<操作符,就会使用stone类重载的<比较方法。
STL源码剖析学习-体系结构与内核分析-1_第11张图片
特化:hash类本来是一个泛化的类;但template<>表明要进行特化的实现。
STL源码剖析学习-体系结构与内核分析-1_第12张图片
偏特化:有函数模板中参数个数维度的偏特化、范围维度上的偏特化,如下所示包括指针类型的偏特化。
STL源码剖析学习-体系结构与内核分析-1_第13张图片

你可能感兴趣的:(STL/C++)