上海做网站的公司名称/网红推广团队去哪里找
内存分配器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> //对象构造,使用可变参数_Argsvoidconstruct(_Up* __p, _Args&&... __args) //参数args构造_Up对象,forward转发保持参数左右值属性及const属性{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }template<typename _Up>voiddestroy(_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; }; //另一类型的内存分配命名为othertypedef 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)等同于&xaddress(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允许为0allocate(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> //泛化的对象构造操作,使用可变参数_Argsvoid //参数args构造_Up对象,forward转发保持参数左右值属性及const属性construct(_Up* __p, _Args&&... __args){ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }template<typename _Up> //析构函数模板,泛化的对象析构操作,调用对象__p的析构函数voiddestroy(_Up* __p) { __p->~_Up(); } //调用_Up析构函数完成析构操作};//内存分配类中重载的运算符template<typename _Tp> //重载==运算符,相等时返回trueinline booloperator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&){ return true; }template<typename _Tp> //重载!=运算符,不等时返回falseinline booloperator!=(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