:allocator

<memory>中的allocator作爲STL中默認的內存分配器,它的定義如下:

template<typename _Tp>
class allocator: public __allocator_base<_Tp>{
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<typename _Tp1>
      struct rebind{ typedef allocator<_Tp1> other; };

      allocator() throw() { }

      allocator(const allocator& __a) throw()
      : __allocator_base<_Tp>(__a) { }

      template<typename _Tp1>
      allocator(const allocator<_Tp1>&) throw() { }

      ~allocator() throw() { }
};
template<>
class allocator<void>
{
public:
      typedef size_t      size_type;
      typedef ptrdiff_t   difference_type;
      typedef void*       pointer;
      typedef const void* const_pointer;
      typedef void        value_type;

      template<typename _Tp1>
      struct rebind
      { typedef allocator<_Tp1> other; };
 };

就是一些typedef和對void進行了特化。它的構造函數和析構函數都不拋出異常。rebind先不涉及。真正幹活的是父類__allocator_base。那__allocator_base又是何方神聖呢?

namespace std
{
     template<typename _Tp>
     using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}

__gnu_cxx是命名空間,__allocator_base是__gnu_cxx命名空間中new_allocator<_Tp>的別名。而在__gnu_cxx命名空間中,我們見到了new_allocator:

  template<typename _Tp>
  class new_allocator
  {
  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<typename _Tp1>
      struct rebind
      { typedef new_allocator<_Tp1> other; };

      new_allocator() noexcept { }

      new_allocator(const new_allocator&)noexcept { }

      template<typename _Tp1>
      new_allocator(const new_allocator<_Tp1>&) noexcept{ }

      ~new_allocator() noexcept { }

      pointer
      allocate(size_type __n, const void* = 0)
      { 
	if (__n > this->max_size())
	  std::__throw_bad_alloc();

	return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      }

      void
      deallocate(pointer __p, size_type)
      { ::operator delete(__p); }

      size_type
      max_size() const _GLIBCXX_USE_NOEXCEPT
      { return size_t(-1) / sizeof(_Tp); }

      void 
      construct(pointer __p, const _Tp& __val) 
      { ::new((void *)__p) _Tp(__val); }

      void 
      destroy(pointer __p) { __p->~_Tp(); }
    };

我們看見了熟悉的allocate,deallocate,construct和destroy。

allocate使用::operator new申請內存,deallocate使用::operator delete釋放內存,construct使用placement new在指定的內存上構造對象,destroy析構對象。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章