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

分配器(allocator)简说

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

在这里插入图片描述

容器的元素大小是一样的,无论数量的多少,所以容器中的每个元素不必记录每个元素的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的东西;
在这里插入图片描述

容器(Container)的背后需要分配器(allocator)支持对内存的使用和操作,但写程序时最好不要直接使用分配器,直接使用容器或者New/delete即可。
下述是容器源码中隐藏使用的分配器代码,在使用容器的时候我们不需要显示调用分配器。通过源码也可以看出,在类模板中,分配器这个参数是缺省提供的。
在这里插入图片描述

下述分配器的源码应该是GNUC的编译版本,VC中不一定适用。
在这里插入图片描述

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

面向对象程序设计的思想希望将数据的操作和方法绑定在一起;
在这里插入图片描述

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

而泛型编程希望将数据的操作和方法分开来,它们之间关联的纽带是 iterator迭代器(泛化指针)。
在这里插入图片描述
在这里插入图片描述

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

操作符重载的基本写法:
在这里插入图片描述
下图是STL的list迭代器的类,迭代器是一种泛化指针,因此迭代器的类一般要模仿指针的操作,因此需要把与指针相关的操作符进行重载。下图所示:重载了*、->、++。
在这里插入图片描述

类模板/模板类
在这里插入图片描述
template / typename 关键字表明这是一个泛化的数据类型,在使用这个类的时候要明确指明T的数据类型。
函数模板和操作符重载的一个例子: 定义了一个类stone,重载了<操作符。在调用模板函数min的时候,指明数据类型是stone对象,而min用到了<操作符,就会使用stone类重载的<比较方法。
在这里插入图片描述
特化:hash类本来是一个泛化的类;但template<>表明要进行特化的实现。
在这里插入图片描述
偏特化:有函数模板中参数个数维度的偏特化、范围维度上的偏特化,如下所示包括指针类型的偏特化。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值