内存分配器allocator
1,内存分配器隐藏在容器背后工作,STL的操作对象存放在容器内,而容器需要配置一定的空间。
2,空间不一定是内存,可以是磁盘或其他辅助存储介质,但一般情况下allocator配置对象为内存。
3,内存配置操作由allocate()负责,内存释放操作由deallocate()负责;对象构造操作由construct()负责,对象析构操作由destory()负责。
4,C++本身不直接支持指针所指对象的类型判断,也不支持对象析构函数是否为trivial的判断,value_type()和__type_traits<>如何实现后续详解。
allocator模板类定义如下:
namespace std _GLIBCXX_VISIBILITY(default)
{
template<typename _Tp> //模板类allocator<_Tp>
class allocator : public __allocator_base<_Tp>
{
public: //类型定义,__alloc_traits中详细介绍
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> //重绑定,获得_Tp1的内存分配器allocator<_Tp1>
struct rebind //重新绑定模板类型_Tp1并将allocator<_Tp1>重命名为other
{ typedef allocator<_Tp1> other; };
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
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> //模板类allocator的特例化版本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 true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
template<typename _Up, typename... _Args> //对象构造,使用可变参数_Args
void
construct(_Up* __p, _Args&&... __args) //参数args构造_Up对象,forward转发保持参数左右值属性及const属性
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up>
void
destroy(_Up* __p) { __p->~_Up(); } //对象析构,调用_Up析构函数完成析构操作
};
}
继承自__allocator_base如下:
namespace std
{
template<typename _Tp>
using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
//使用std中size_t和ptrdiff_t定义,为了程序的可移值性适应不同平台
using std::size_t; //表unsigned类型大小
using std::ptrdiff_t; //表两指针之间距离
template<typename _Tp>
class new_allocator
{
public: //类型定义,后续__alloc_traits中详细介绍
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 //重绑定,在当前内存分配类型_Tp中定义另一类型_Tp1的内存分配
{ typedef new_allocator<_Tp1> other; }; //另一类型的内存分配命名为other
typedef std::true_type propagate_on_container_move_assignment;
new_allocator() _GLIBCXX_USE_NOEXCEPT { } //默认构造函数
new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } //拷贝构造函数
template<typename _Tp1> //构造函数模板,泛化的拷贝操作
new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
~new_allocator() _GLIBCXX_USE_NOEXCEPT { } //默认析构函数
pointer //返回指向对象__x的指针,算式a.address(x)等同于&x
address(reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); } //std::__addressof()获取左值表达式的地址
const_pointer //返回指向对象的const指针
address(const_reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
pointer //配置内存空间,返回n个Tp类型内存空间,_n允许为0
allocate(size_type __n, const void* = static_cast<const void*>(0))
{
if (__n > this->max_size()) //检查可最大配置内存空间
std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); //封装::operator new分配内存空间
}
void //释放已配置空间
deallocate(pointer __p, size_type) // __p不允许为空指针.
{
::operator delete(__p); //封装::operator delete释放内存
}
size_type //返回可成功配置的最大值
max_size() const _GLIBCXX_USE_NOEXCEPT
{ return size_t(-1) / sizeof(_Tp); }
template<typename _Up, typename... _Args> //泛化的对象构造操作,使用可变参数_Args
void //参数args构造_Up对象,forward转发保持参数左右值属性及const属性
construct(_Up* __p, _Args&&... __args)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up> //析构函数模板,泛化的对象析构操作,调用对象__p的析构函数
void
destroy(_Up* __p) { __p->~_Up(); } //调用_Up析构函数完成析构操作
};
//内存分配类中重载的运算符
template<typename _Tp> //重载==运算符,相等时返回true
inline bool
operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
{ return true; }
template<typename _Tp> //重载!=运算符,不等时返回false
inline bool
operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
{ return false; }
} // namespace
构造和析构基本工具:construct()和destory()
namespace std _GLIBCXX_VISIBILITY(default)
{
template<typename _T1, typename... _Args> //构造函数模板,模板参数为对象类型和对象所需参数
inline void //构造对象__p,forward转发保持__args参数属性
_Construct(_T1* __p, _Args&&... __args)
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
template<typename _T1> //拷贝构造函数模板,模板参数为对象类型
inline void //拷贝对象
_Construct_novalue(_T1* __p)
{ ::new(static_cast<void*>(__p)) _T1; }
template<typename _Tp> //析构函数模板,模板参数为对象类型
inline void //对象析构,接受一个指针,将指针所指对象析构
_Destroy(_Tp* __pointer)
{ __pointer->~_Tp(); }
template<bool> //模板类 _Destroy_aux<bool>
struct _Destroy_aux
{
template<typename _ForwardIterator>
static void //析构迭代器范围内所有元素
__destroy(_ForwardIterator __first, _ForwardIterator __last)
{
for (; __first != __last; ++__first) //for循环,调用_Destroy析构对象
std::_Destroy(std::__addressof(*__first));
}
};
template<> //模板类 _Destroy_aux的特例化版本 _Destroy_aux<true>
struct _Destroy_aux<true>
{
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator, _ForwardIterator) { }
};
template<typename _ForwardIterator> //模板类_Destroy<_ForwardIterator>
inline void //析构[first, last)范围内所有对象
_Destroy(_ForwardIterator __first, _ForwardIterator __last)
{ //如果destructor为trivial,不需要一次次调用析构函数
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type; //获取迭代器_ForwardIterator所指对象类型
static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
//__has_trivial_destructor(_Value_type)判断该类型析构函数是否trivial
//__type_traits提取类型特性,判断存在默认构造函数、拷贝构造函数、赋值操作、析构函数
//如果存在则可使用对应函数完成构造、拷贝、赋值、析构操作,如果不存在则需要采用内存直接操作
//若为true,std::_Destroy_aux<true>::__destroy(__first, __last)
//若为false,循环整个范围,每个对象调用std::_Destroy(std::__addressof(*__first))
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
__destroy(__first, __last);
}
template<bool> //模板类 _Destroy_aux<bool>
struct _Destroy_n_aux
{
template<typename _ForwardIterator, typename _Size>
static _ForwardIterator //析构迭代器__first开始的__count个元素
__destroy_n(_ForwardIterator __first, _Size __count)
{
for (; __count > 0; (void)++__first, --__count)
std::_Destroy(std::__addressof(*__first));
return __first;
}
};
template<> //模板类的特例化版本_Destroy_aux<true>
struct _Destroy_n_aux<true>
{
template<typename _ForwardIterator, typename _Size>
static _ForwardIterator
__destroy_n(_ForwardIterator __first, _Size __count)
{
std::advance(__first, __count);
return __first;
}
};
template<typename _ForwardIterator, typename _Size> //函数模板
inline _ForwardIterator //析构迭代器__first开始的__count个元素
_Destroy_n(_ForwardIterator __first, _Size __count)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type; //迭代器所指元素类型
static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
//根据对象是否有析构函数,调用模板类_Destroy_n_aux<bool>下__destroy_n函数
return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
__destroy_n(__first, __count);
}
template<typename _ForwardIterator, typename _Allocator> //析构函数模板,模板参数为迭代器类型和内存分配器
void //可使用自定义内存分配器,析构指定迭代器范围内元素
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator& __alloc)
{ //调用内存分配器_Allocator的destroy函数析构元素
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __first != __last; ++__first)
__traits::destroy(__alloc, std::__addressof(*__first));
}
template<typename _ForwardIterator, typename _Tp> //析构函数模板,模板参数为迭代器类型和对象类型
inline void //内存分配器为std::allocator,析构迭代器范围内元素
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>&)
{
_Destroy(__first, __last);
}
} // namespace std