vs 2005中实现的各种容器其默认的内存分配模型是allocator,它声明在<xmemory>文件中。
template<class _Ty> class allocator
: public _Allocator_base<_Ty>
{ // generic allocator for objects of class _Ty
public:
typedef _Allocator_base<_Ty> _Mybase;
typedef typename _Mybase::value_type value_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef const value_type * const_pointer;
typedef const value_type & const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<class _Other>
struct rebind
{ // convert an allocator<_Ty> to an allocator <_Other>
typedef allocator<_Other> other;
};
// 构造函数,do nothing
allocator() throw () () { }
allocator(const allocator<_Ty>&) throw () (){ }
template<class _Other>
allocator(const allocator<_Other>&) throw () () { }
// 赋值运算符,do nothing
template<class _Other>
allocator<_Ty>& operator=(const allocator<_Other>&) { return (*this); }
// 返回_Val的地址
pointer address(reference _Val) const { return (&_Val); }
const_pointer address(const_reference _Val) const{ return (&_Val); }
// 分配能容纳下_Count个_Ty类型元素的缓冲区
pointer allocate(size_type _Count){ return (_Allocate(_Count, (pointer)0)); }
// 释放_Ptr所指内存缓冲区
void deallocate(pointer _Ptr, size_type){ ::operator delete(_Ptr);}
// 在_Ptr地址处构造值为_Val的元素
void construct(pointer _Ptr, const _Ty& _Val){ _Construct(_Ptr, _Val); }
// 析构_Ptr地址处的对象
void destroy(pointer _Ptr){ _Destroy(_Ptr); }
// allocator能分配的类型为_Ty的最大元素个数
size_t max_size() const throw () ()
{
size_t _Count = (size_t)(-1) / sizeof (_Ty);
return (0 < _Count ? _Count : 1);
}
};
allocator派生自_Allocator_base,在_Allocator_base中只定义了一个类型别名value_type,如下:
allocator中的value_type类型别名就是通过_Allocator_base中的类型别名取得的。
template<class _Ty>
struct _Allocator_base
{
typedef _Ty value_type;
};
template<class _Ty>
struct _Allocator_base<const _Ty>
{
typedef _Ty value_type;
};
allocator的构造函数和赋值运算符都没有实质的作用。它主要定义了四组函数:取元素地址、分配和释放缓冲区、构造和析构元素、返回能分配的最大元素个数。
函数allocate和deallocate是对new和delete的简单包装,在allocate中调用了_Allocate函数。通过这个函数分配出的内存并没有初始化。
namespace std{
template<class _Ty> inline
_Ty *_Allocate(size_t _Count, _Ty *)
{
if (((size_t)(-1) / _Count) < sizeof (_Ty)) // 确保不会超过最大限额
throw std::bad_alloc(NULL);
return ((_Ty *)::operator new(_Count * sizeof (_Ty)));
}
}
函数construct和destroy是在指定地址构造和析构元素,它们与前两个的主要区别在于内存已经分配好了。
它们又分别调用了_Construct和_Destroy函数,这两个函数在其它地方也有用到。
namespace std{
template<class _T1, class _T2> inline
void _Construct(_T1 *_Ptr, const _T2& _Val)
{ // construct object at _Ptr with value _Val
void *_Vptr = _Ptr;
::new (_Vptr) _T1(_Val); // 在指定内存位置构造元素
}
template<class _Ty> inline // 调用析构函数进行析构
void _Destroy(_Ty *_Ptr){ (_Ptr)->~_Ty(); }
// 对于指向char和wchar_t的版本进行特化,do nothing
template<> inline void _Destroy(char *) { }
template<> inline void _Destroy(wchar_t *) { }
}