####类模板 allocator####
类模板 allocator 中有一个模板形参 _Tp 用来表示为哪种类型的对象分配内存空间,其使用默认的 alloc 进行内存分配。其内部的构造函数和析构函数都是空的。
allocate 函数中调用 _Alloc 的 allocate 函数进行内存分配。其中 _Alloc 是 alloc 的在类中定义的成员类型别名。
这里允许申请的空间大小为 0 。第二个 void 指针在函数中没有被使用。_Alloc 中的 allocate 函数返回的是 void* ,但当前函数的返回的是 _Tp* ,因此加了一个强制类型转换。
_Tp* allocate(size_type __n, const void* = 0) {
return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)))
: 0;
}
deallocate 函数和 allocate 函数类似,也是直接调用 _Alloc 的内存释放函数 (注意这里的内存释放和通常认为的内存释放不同,_Alloc 中对于小于 _MAX_BYTES 的内存,会放到自由列表中重新进行使用)。
void deallocate(pointer __p, size_type __n)
{ _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
construct 和 destory 主要用来构建对象和销毁对象。对象的构建通过定位 new 来进行构建 (placement new)。定位 new 用来在已分配的内存上构建一个对象,destory 通过调用对象的析构函数来销毁对象。这里的 construct 和 destory 都既不涉及到内存的申请也不涉及到内存的释放。
void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
void destroy(pointer __p) { __p->~_Tp(); }
在 allocator 内部还有一个内嵌的类模板 在该类模板中定义了一个成员类型为 other,这个会在 alloc_traits 中用到。
template <class _Tp1> struct rebind {
typedef allocator<_Tp1> other;
};
allocator 有一个特化,如下所示,当_Tp 为 void 时,会采用以下内容进行实例化。 这个函数中没有成员函数的定义,只是定义了一些公有的成员类型。
template<>
class allocator<void> {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
// nested class
template <class _Tp1> struct rebind {
typedef allocator<_Tp1> other;
};
};
####类模板 __allocator####
__allocator 可以看成内存适配器 _Alloc 的一个适配器 ,模板形参 _Tp 表示为何种类型的对象分配内存,_Alloc 为内存分配器 。通过它来进行实际的内存分配。
template <class _Tp, class _Alloc>
struct __allocator {
......
};
__allocator 内部显示定义了一个 _Alloc 类型的对象。
_Alloc __underlying_alloc;
和前面 allocator 一样内部也定义了一个 other 的成员类型。
template <class _Tp1> struct rebind {
typedef __allocator<_Tp1, _Alloc> other;
};
__allocator 中定义了两个拷贝构造函数来初始化对象。 第一个拷贝构造函数是用一个模板实参相同的对象来进行初始化。第二个用一个模板实参不同的对象来进行初始化。
第一个函数没有讨论的必要,对于第二个函数从逻辑上看,好像不太合理,但其实是合理的,因为拷贝构造函数中是只是对 _Alloc 类型的成员变量 __underlying_alloc 进行了初始化。第一个模板实参是什么类型并不影响当前对象。
__allocator(const __allocator& __a) __STL_NOTHROW
: __underlying_alloc(__a.__underlying_alloc) {}
template <class _Tp1, _Alloc>
__allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW
: __underlying_alloc(__a.__underlying_alloc) {}
其内部的实现和上面的 allocator 不同之处在于前面的 allocator 是用 alloc 的静态函数来实现,并没有声明对象,而 __allocator 中定义了一个 _Alloc 类型的对象,由对象来进行内存的分配。
__allocator 有一个偏特化,如下所示,当第一个模板实参为 void 是采用下面的定义进行实例化。
template <class _Alloc>
class __allocator<void, _Alloc> {
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class _Tp1> struct rebind {
typedef __allocator<_Tp1, _Alloc> other;
};
};
_Alloc_traits 也可以看成是一个 _Allocator 的适配器。 首先定义了一个静态的 bool 类型的常量 _S_instanceless,在这里初始化为false 。同时在内部定义了一个成员类型 allocator_type 。_S_instanceless 为 false 表示 _Allocator 的不同实例之间是有区别的,当 _S_instanceless 为 true 时表示 _Allocator 的不同实例之间是没有区别的。
从上面的声明可以看成 _Allocator 中应该有一个类似于 allocator 或者 __allocator 中定义的嵌套模板 rebind。同时这里应该也可以运用自己定义的内存管理实现来实例化 _Allocator。只要在你的实现中有这个嵌套模板 rebind 的定义。
template <class _Tp, class _Allocator>
struct _Alloc_traits
{
static const bool _S_instanceless = false;
typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other
allocator_type;
};
_Alloc_traits 还有五个偏特化的定义分别为 分别是用 allocator,__malloc_alloc_template,__default_alloc_template,debug_alloc,__allocator来 作为 _Alloc_traits 的第二个模板实参。
其中 __allocator 中又可以用 _malloc_alloc_template ,__default_alloc_template ,debug_alloc 来进行实例化,故一个有七个不同的特化选择。其中每个特化中的 _S_instanceless 都初始化为 true 。且每个特化的定义中多了一个 _Alloc_type ,该类型能够通过静态的接口为 Tp 类型的对象实现内存的分配和回收,就是实际中可以通过 allocate_type 的实例进行类存分配和回收,也可一通过 _Alloc_type 的静态实现(可以通过作用域运算符 :: 进行调用)来实现内存的分配和回收。
template <class _Tp, class _Tp1>
struct _Alloc_traits<_Tp, allocator<_Tp1> >
{
static const bool _S_instanceless = true;
typedef simple_alloc<_Tp, alloc> _Alloc_type;
typedef allocator<_Tp> allocator_type;
};
template <class _Tp, class _Tp1, bool __thr, int __inst>
struct _Alloc_traits<_Tp,
__allocator<_Tp1,
__default_alloc_template<__thr, __inst> > >
{
static const bool _S_instanceless = true;
typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
_Alloc_type;
typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
allocator_type;
};
STL的内存分配器(一)</br> STL的内存分配器(二)</br> STL的内存分配器(三)</br>