您的位置:首页 > 其它

SGISTL源码探究-默认使用的配置器

2017-09-07 18:25 169 查看

前言

在上节中我们主要分析了
chunk_alloc
函数,在本小节中,我们先对第一级配置器和第二级配置器的使用做个整理,随后再介绍空间配置器提供的初始化未初始化空间的接口。

默认使用的配置器

当我们使用
vector
这些容器时,其实是默认指定了使用的空间配置器的,比如
vector
在源码中的模板头是这样的
template <class T, class Alloc = alloc>
,默认指定了配置器为
alloc


alloc
则代表具体的哪一个配置器。

在SGISTL源码中是这样指定
alloc
的,它是一个typedef。

# ifdef __USE_MALLOC

typedef malloc_alloc alloc;
...

#else
...
typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc;


如果宏定义了
__USE_MALLOC
,则使用第一级配置器,如果没有,则使用第二级配置器。

__USE_MALLOC
的定义又涉及到了其他宏,最终由gcc的版本而定,我不知道当时gcc的版本是多少,就不太明白
__USE_MALLOC
到底定义没有,因为它是一个条件编译。而在《STL源码剖析》书上说的
__USE_MALLOC
没有定义,那应该当时SGISTL默认使用的就是第二级配置器。

不论使用的哪一种,SGISTL都统一了配置器的接口,代码如下

template<class T, class Alloc>
class simple_alloc {

public:
static T *allocate(size_t n)
{ return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
static T *allocate(void)
{ return (T*) Alloc::allocate(sizeof (T)); }
static void deallocate(T *p, size_t n)
{ if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
static void deallocate(T *p)
{ Alloc::deallocate(p, sizeof (T)); }
};


可以看到申请/释放空间都统一调用的是
Alloc
的接口,而
Alloc
默认指定是
alloc
,
alloc
对应的是第一级配置器/第二级配置器。

你可能还会有疑问,即那么
simple_alloc
在哪里进行实例化呢,毕竟没有实例化的话,那些容器根本就用不了空间配置器提供的外部接口。

答案是就在容器内部进行,如
vector
中的
typedef simple_alloc<value_type, Alloc> data_allocator
,指定了分配的单位以及使用的配置器,在
vector
内部中分配及释放内存都使用
simple_alloc
提供的接口。

理解以上所述十分关键,因为这涉及到空间配置器与其他STL组件之间的联系。总的来说,就是空间配置器里面分第一级配置器和第二级配置器,不论是用哪一个,都封装了一套标准的接口(
simple_alloc
)供其他STL组件使用,而其他组件在内部定义属于自己的空间配置器(即指定分配的单位等)

小结

在本小节中,我们从宏观的角度来观察了空间配置器和其他STL组件的一些联系,这对我们把握STL整体很有帮助。空间配置器中还有一些函数没有进行分析,如
uninitalized_copy
等函数,由于它们涉及到迭代器的类别等方面的知识,还是放在讲完了迭代器再分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐