allocator
vs的 allocator 位置
#include <xmemory>
vs 中的實作:
大概vs認為如果是内部封裝的,都會在前面加下劃線。是以,在xmemory頭檔案有個define
#define _ALLOCATOR allocator
然後,目前檔案的下面就有了
_ALLOCATOR
的類模闆.
這裡有兩個版本,一個是普通版本,一個是特化版本。
/*
template<class _Ty>
class _ALLOCATOR : public _Allocator_base< _Ty>
{
//...
};
template<> class _ALLOCATOR<void>
{
//...
};
*/
稍微分析一下:
由于我不是太喜歡開頭加各種下劃線,是以我就自己修改下命名了。。
Allocator_base 類
template<class Ty>
struct Allocator_base
{ // base class for generic allocators
typedef Ty value_type;
};
// TEMPLATE CLASS _Allocator_base<const _Ty>
template<class Ty>
struct Allocator_base<const Ty>
{
//base class for generic allocators for const Ty
typedef Ty value_type;
};
注:
- 我把 _Ty 寫成了 Ty
- 我把 _Allocator_base 寫成了 Allocator_base
其實上面寫得很清楚,隻是定義了模闆 傳入參數的類型, 以後 咱們傳入的類型就在模闆裡面就是這個。
allocator
其實這個類并不是太難了解,不過我是一邊看類,一邊向上翻那幾個函數的,這裡有幾個需要記錄下:
- _FARQ 這個宏
- 後面注釋:specify standard memory model 翻譯就是指定标準記憶體模型
- 由于後面是空的,大概應該是給編譯器,或者其他的使用,至少不是我
- (這裡我是忽略的,因為我認為學習應該先分層?主要目的是想看看allocator)
- _Allocate 又是帶下劃線的,這是個模闆函數
/* 這裡是源碼 ,但是我不是太會直接閱讀這樣的源碼,是以我進行了替換 template<class Ty> inline Ty _FARQ *_Allocate(_SIZT _Count, Ty _FARQ *) { // allocate storage for _Count elements of type _Ty void *_Ptr = 0; if (_Count <= 0) _Count = 0; else if (((_SIZT)(-1) / sizeof (_Ty) < _Count) || (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0) _THROW_NCEE(bad_alloc, 0); return ((_Ty _FARQ *)_Ptr); } */ //替換後 這個就是擷取一段記憶體的函數 template< typename Ty > Ty* Func_Allocate(size_t Count, Ty*) { void* ptr = nullptr; if (Count <= 0) //其實這裡size_t 就是unsigned..但是我也不知道他為啥這樣寫,俺也不敢問... { Count = 0; } else if( ((size_t)(-1) / sizeof(Ty) < Count) // 定義了邊界,-1轉換成unsigned 就是unsigned的最大值。最多擷取元素個數,還小于這個個數,就傳回bad allocat || (ptr = ::operator new(Count* sizeof(Ty)) == nullptr) //這裡做了擷取記憶體的操作~如果沒new成功,就傳回 bad allocat ) { throw bad_alloc(0); } return ( (Ty*)ptr); }
- _Construct 也是個帶下劃線的模闆函數,和上面一樣
/* 同上,這是他的源碼 template<class _Ty1, class _Ty2> inline void _Construct(_Ty1 _FARQ *_Ptr, _Ty2&& _Val) { // construct object at _Ptr with value _Val void _FARQ *_Vptr = _Ptr; ::new (_Vptr) _Ty1(_STD forward<_Ty2>(_Val)); } template<class _Ty1> inline void _Construct(_Ty1 _FARQ *_Ptr) { // construct object at _Ptr with default value void _FARQ *_Vptr = _Ptr; ::new (_Vptr) _Ty1(); } */ template<typename Ty1, typename Ty2> void Func_Construct(Ty1 Ptr, Ty2 Val) { void* Vptr = Ptr; ::new(Vptr) Ty1(::std::forward<Ty2>(Val)); //這裡進行了初始化,Ptr指向的對象進行了初始化 }
- _Destroy 調用析構的函數
/* 源碼大概就長這樣,很好懂
template<class _Ty> inline
void _Destroy(_Ty _FARQ *_Ptr)
{ // destroy object at _Ptr
_Ptr->~_Ty();
}
*/
template<typename Ty> inline
void Func_Destroy(Ty* Ptr)
{
Ptr->~Ty();
}
/* 同理 這裡是源碼
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 _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 this type to _ALLOCATOR<_Other>
typedef _ALLOCATOR<_Other> other;
};
pointer address(reference _Val) const
{ // return address of mutable _Val
return ((pointer) &(char&)_Val);
}
const_pointer address(const_reference _Val) const
{ // return address of nonmutable _Val
return ((const_pointer) &(char&)_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 construct(pointer _Ptr, _Ty&& _Val)
{ // construct object at _Ptr with value _Val
::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val));
}
template<class _Other>
void construct(pointer _Ptr, _Other&& _Val)
{ // construct object at _Ptr with value _Val
::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Other>(_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);
}
};
*/
// 這裡是我替換後的版本
template < typename Ty >
class allocator : public Allocator_base< Ty >
{
public:
typedef Allocator_base<Ty> Mybase;
typedef typename Mybase::value_type value_type; //這兩行,是拿到了父類定義的value_type
typedef value_type* pointer; //定義了Ty的指針 在這裡叫 pointer
typedef value_type& reference; //定義了Ty的引用 在這裡叫 reference
typedef const value_type* const_pointer; // const 指針
typedef const value_type& const_reference; // const 引用
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template < typename Other >
struct rebind
{
//将 allocator< Other > 定義為 other 類型
typedef allocator< Other > other;
};
//---------- 這裡開始算是 alocator 的各種method -----
//--begin: 這裡是擷取指針的函數
pointer address(reference Val) const
{ // return address of mutable Val
return ((pointer) &(char&)Val); //這裡猜測使用char作為類型轉換的中介,大概是因為char是基本類型中最小的,誰都可以轉換,且都能讀取到東西
}
const_pointer address(const_reference Val) const
{ // return address of nonmutable Val
return ((const_pointer) &(char&)Val);
}
//--end
//--begin: 構造函數,拷貝構造,指派操作符
allocator() throw()
{ // construct default allocator (do nothing)
}
allocator(const allocator<Ty>&) throw()
{ // construct by copying (do nothing)
}
template<typename Other>
allocator(const allocator<Other>&) throw()
{ // construct from a related allocator (do nothing)
}
template<typename Other>
allocator<Ty>& operator=(const allocator<Other>&)
{ // assign from a related allocator (do nothing)
return (*this);
}
//--end.
//-- begin: 這裡是最重要的功能函數擷取記憶體,以及釋放記憶體
void deallocate(pointer Ptr, size_type)
{
::operator delete(Ptr);
}
pointer allocate(size_type Count)
{
return (Func_Allocate(Count, (pointer)0)); //這裡調用之前的一個全局函數
}
pointer allocate(size_type Count, const void*)
{
return allocate(Count); //這裡調用了上面的函數 allocate
}
//--end
//-- begin: 這裡進行初始化和銷毀~
void construct(pointer Ptr, const Ty& Val)
{ // construct object at Ptr with value Val
Func_Construct(Ptr, Val);
}
void construct(pointer Ptr, Ty&& Val)
{ // construct object at Ptr with value Val
::new ((void*)Ptr) Ty(::std::forward<Ty>(Val));
}
template<class Other>
void construct(pointer Ptr, Other&& Val)
{ // construct object at Ptr with value Val
::new ((void* )Ptr) Ty(::std::forward<Other>(Val));
}
void destroy(pointer Ptr)
{ // destroy object at Ptr
Destroy(Ptr);
}
//-- end
//-- begin: 擷取能夠存儲的最大個數
size_t max_size() const throw()
{
size_t Count = (size_t)(-1) / sizeof(Ty);
return (0 < Count ? Count : 1);
}
};