三种的allocator实现源代码的对比
最近看空间配置器的内容,把ACE的ACE_Allocator类实现,SGI的allocator类实现和MS的allocator实现也参考了侯捷先生的《STL源码剖析》,有不少收获。
我听说是有说明STL中allocator实现标准的文件,但我没有找到,据我实验推测,标准allocator需要实现rebind,allocate,deallocate,max_size和构造及析构函数一共六个函数。也就是说,我要写一个在标准vector可用的allocator最小只需要上面的几个接口实现就可以了。
先来说一下微软的allocator。文件名是xmemory,我觉得是最没有看头的,基本就是new和delete的封装,为了迎合C++标准库的标准做的。没有什么技巧,更别说微妙了。上面的六个接口下面都有实现。
[cpp]
// TEMPLATE CLASS allocator
emplate<class _Ty>
class allocator
: public _Allocator_base<_Ty>
{ // generic allocator for objects of class _Ty
ublic:
typedef _Allocator_base<_Ty> _Mybase;
typedef typename _Mybase::value_type value_type;
typedef value_type _FARQ *pointer;
typedef value_type _FARQ& reference;
typedef const value_type _FARQ *const_pointer;
typedef const value_type _FARQ& const_reference;
typedef _SIZT size_type;
typedef _PDFT difference_type;
template<class _Other>
struct rebind
{ // convert an allocator<_Ty> to an allocator <_Other>
typedef allocator<_Other> other;
};
pointer address(reference _Val) const
{ // return address of mutable _Val
return (&_Val);
}
const_pointer address(const_reference _Val) const
{ // return address of nonmutable _Val
return (&_Val);
}
allocator() _THROW0()
{ // construct default allocator (do nothing)
}
allocator(const allocator<_Ty>&) _THROW0()
{ // construct by copying (do nothing)
}
template<class _Other>
allocator(const allocator<_Other>&) _THROW0()
{ // construct from a related allocator (do nothing)
}
template<class _Other>
allocator<_Ty>& operator=(const allocator<_Other>&)
{ // assign from a related allocator (do nothing)
return (*this);
}
void deallocate(pointer _Ptr, size_type)
{ // deallocate object at _Ptr, ignore size
::operator delete(_Ptr);
}
pointer allocate(size_type _Count)
{ // allocate array of _Count elements
return (_Allocate(_Count, (pointer)0));
}
pointer allocate(size_type _Count, const void _FARQ *)
{ // allocate array of _Count elements, ignore hint
return (allocate(_Count));
}
void construct(pointer _Ptr, const _Ty& _Val)
{ // construct object at _Ptr with value _Val
_Construct(_Ptr, _Val);
}
void destroy(pointer _Ptr)
{ // destroy object at _Ptr
_Destroy(_Ptr);
}
_SIZT max_size() const _THROW0()
{ // estimate maximum array size
_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
return (0 < _Count ? _Count : 1);
}
};
2. SGI STL实现的allocator。作为C++作者都主推的STL实现版本,当然是符合标准的。它的主站:http://www.sgi.com/tech/stl/ ,怎么去配置调试我已经在上一篇讲过了。它的实现通过阅读侯捷先生的书得到更深入的了解。当然代码与侯先生解析的那个版本有一些不同,无非是加了一些代理以及包装之类的,影响不大。我们可以看到这些接口大都通过__sgi_alloc中的函数去实现。
[cpp]
template <class _Tp>
struct __stlport_class
{ typedef _Tp _Type; };
template <class _Tp>
class allocator //: public _AllocatorAux<_Tp>
/* A small helper struct to recognize STLport allocator implementation
* from any user specialization one.
*/
: public __stlport_class<allocator<_Tp> >
{
public:
typedef _Tp value_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if defined (_STLP_MEMBER_TEMPLATE_CLASSES)
template <class _Tp1> struct rebind {
typedef allocator<_Tp1> other;
};
#endif
allocator() _STLP_NOTHROW {}
#if defined (_STLP_MEMBER_TEMPLATES)
template <class _Tp1> allocator(const allocator<_Tp1>&) _STLP_NOTHROW {}
#endif
allocator(const allocator<_Tp>&) _STLP_NOTHROW {}
#if !defined (_STLP_NO_MOVE_SEMANTIC)
allocator(__move_source<allocator<_Tp> > src) _STLP_NOTHROW {}
#endif
~allocator() _STLP_NOTHROW {}
pointer address(reference __x) const {return &__x;}
const_pointer address(const_reference __x) const { return &__x; }
// __n is permitted to be 0. The C++ standard says nothing about what the return value is when __n == 0.
_Tp* allocate(size_type __n, const void* = 0) {
if (__n > max_size()) {
_STLP_THROW_BAD_ALLOC;
}
if (__n != 0) {
size_type __buf_size = __n * sizeof(value_type);
_Tp* __ret = __REINTERPRET_CAST(_Tp*, __sgi_alloc::allocate(__buf_size));
#if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
#endif
return __ret;
}
补充:软件开发 , C++ ,