当前位置:编程学习 > C/C++ >>

三种的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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,