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 *) { } }