配置器:负责空间配置与管理,从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的 class template。
空间配置器:整个 STL 的操作对象都存放在容器之内,而容器一定需要配置空间以存放内容。
空间配置器的标准接口
std::allocator 定义在 <defalloc.h> 中。
template <class T>
inline T* allocate(ptrdiff_t size, T*) {
//@ 为了卸载目前的内存分配异常处理函数,强制C++在内存不够的时候抛出std:bad_alloc。
set_new_handler(0);
//@ 申请size个T类型大小的空间
T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
if (tmp == 0) {
cerr << "out of memory" << endl;
exit(1);
}
return tmp;
}
template <class T>
inline void deallocate(T* buffer) {
::operator delete(buffer);
}
template <class _Tp>
class allocator {
typedef alloc _Alloc;
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
//@ 嵌套一个template,且仅包含唯一成员other,是一个typedef
template <class _Tp1> struct rebind {
typedef allocator<_Tp1> other;
};
//@ 默认构造函数
allocator() __STL_NOTHROW {}
//@ 复制构造函数
allocator(const allocator&) __STL_NOTHROW {}
//@ 泛化的复制构造函数
template <class _Tp1> allocator(const allocator<_Tp1>&) __STL_NOTHROW {}
//@ 析构函数
~allocator() __STL_NOTHROW {}
//@ 返回对象的地址
pointer address(reference __x) const { return &__x; }
//@ 返回const对象的地址
const_pointer address(const_reference __x) const { return &__x; }
//@ 配置空间,如果申请的空间块数不为0,那么调用 _Alloc 也即 alloc 的 allocate 函数来分配内存
_Tp* allocate(size_type __n, const void* = 0) {
return __n != 0 ? static_cast<_Tp*>(
::allocate(__n * sizeof(_Tp)))
: 0;
}
//@ 释放已配置的空间
void deallocate(pointer __p, size_type __n)
{ _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
//@ 返回可成功配置的最大值
size_type max_size() const __STL_NOTHROW
{ return size_t(-1) / sizeof(_Tp); }
//@ 构造对象
void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
//@ 析构
void destroy(pointer __p) { __p->~_Tp(); }
};
总结
- 空间申请:allocate,空间释放:deallocate。
- 对象构造 construct,对象析构:destroy。
- allocator/deallocate 只是 ::operator::new 和 ::operator::delete) 的一层薄薄的包装,并没有考虑到任何效率上的强化。