STL源码剖析读书笔记2
来源:互联网 发布:1688端口是干嘛的 编辑:程序博客网 时间:2024/05/22 13:11
空间适配器allocator
为什么不说allocator是内存适配器而是空间适配器,原因就是你可以写
allocat直接向硬盘取空间。
allocator标准接口
设计一个简单的空间配置器JJ::allocator
_STD_BEGIN // 这里是内存分配 // TEMPLATE FUNCTION _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); } // 使用 placement new 进行对象的拷贝构造放置 // TEMPLATE FUNCTION _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)); } // 使用 placement new 进行对象的默认构造放置 template<class _Ty1> inline void _Construct(_Ty1 _FARQ *_Ptr) { // construct object at _Ptr with default value void _FARQ *_Vptr = _Ptr; ::new (_Vptr) _Ty1(); } // 对象销毁(析构函数) // TEMPLATE FUNCTION _Destroy template<class _Ty> inline void _Destroy(_Ty _FARQ *_Ptr) { // destroy object at _Ptr _Ptr->~_Ty(); } // 内嵌字符串类型不用析构,特化版本供优化使用 template<> inline void _Destroy(char _FARQ *) { // destroy a char (do nothing) } template<> inline void _Destroy(wchar_t _FARQ *) { // destroy a wchar_t (do nothing) } #ifdef _NATIVE_WCHAR_T_DEFINED template<> inline void _Destroy(unsigned short _FARQ *) { // destroy a unsigned short (do nothing) } #endif /* _NATIVE_WCHAR_T_DEFINED */ // 根据指针类型选择是否为 POD 数据类型 // TEMPLATE FUNCTION _Destroy_range template<class _Alloc> inline void _Destroy_range(typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al) { // destroy [_First, _Last) _Destroy_range(_First, _Last, _Al, _Ptr_cat(_First, _Last)); } // 非 POD 数据类型需要显示调用析构函数 template<class _Alloc> inline void _Destroy_range(typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al, _Nonscalar_ptr_iterator_tag) { // destroy [_First, _Last), arbitrary type for (; _First != _Last; ++_First) _Dest_val(_Al, _First); } // POD 数据类型不需要调用析构函数 template<class _Alloc> inline void _Destroy_range(typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al, _Scalar_ptr_iterator_tag) { // destroy [_First, _Last), scalar type (do nothing) } // TEMPLATE FUNCTION addressof template<class _Ty> inline _Ty * addressof(_Ty& _Val) { // return address of _Val return ((_Ty *) &(char&)_Val); } // TEMPLATE CLASS _Allocator_base template<class _Ty> struct _Allocator_base { // base class for generic allocators typedef _Ty value_type; }; // 偏特化,去除 const 属性 // 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; }; // TEMPLATE CLASS _ALLOCATOR 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; // 由于在STL容器中allocator是以模板参数传入的,而对于节点型容器, 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) } // 这里使用了 Coercion by Member Template 惯用法 template<class _Other> _ALLOCATOR(const _ALLOCATOR<_Other>&) _THROW0() { // construct from a related allocator (do nothing) } // 这里使用了 Coercion by Member Template 惯用法 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); } // placement new 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); } };
[1] placement new是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。
它的原型如下:
void *operator new( size_t, void *p ) throw() { return p; }使用方法如下:
- 缓冲区提前分配
可以使用堆的空间,也可以使用栈的空间,所以分配方式有如下两种:
class MyClass {…};
char *buf=new char[N*sizeof(MyClass)+ sizeof(int) ] ;
或者char buf[N*sizeof(MyClass)+ sizeof(int) ];
- 对象的构造
MyClass * pClass=new(buf) MyClass;
- 对象的销毁
一旦这个对象使用完毕,你必须显式的调用类的析构函数进行销毁对象。但此时内存空间不会被释放,以便其他的对象的构造。
pClass->~MyClass();
- 内存的释放
如果缓冲区在堆中,那么调用delete[] buf;进行内存的释放;如果在栈中,那么在其作用域内有效,跳出作用域,内存自动释放.
[2] size_t size=sizeof(i);//用sizeof操作得到变量i的类型的大小
ptrdiff_t diff=p2-p1;//指针的减法可以计算两个指针之间相隔的元素个数[3]exit用在main内的时候无论main是否定义成void返回的值都是有效的,并且exit不需要考虑类型,exit⑴等价于return ⑴
- STL源码剖析读书笔记2
- STL源码剖析 -- 读书笔记
- STL源码剖析读书笔记
- STL源码剖析读书笔记
- [读书笔记]《STL源码剖析》
- STL 源码剖析 读书笔记 第一章
- STL源码剖析读书笔记3
- STL源码剖析读书笔记4
- STL源码剖析读书笔记5
- STL源码剖析读书笔记6
- STL源码剖析读书笔记7
- STL源码剖析读书笔记7
- 《STL源码剖析》读书笔记之关联式容器(2)
- 【STL源码剖析读书笔记】【第2章】空间配置器
- STL源码剖析读书笔记之vector
- stl源码剖析读书笔记之allocator
- STL源码剖析(2)
- STL 内存配置器 《STL源码剖析》 读书笔记
- phalcon2.0 dll 下载
- 网站大全
- 找网站
- form表单在前台转json对象
- OpenCL与CNN篇四:CNN从入门到使用
- STL源码剖析读书笔记2
- Ubuntu 16.04.2 LTS 安装 mysql-server_5.7.18-1ubuntu16.10_amd64.deb-bundle.tar
- 客户端程序自动更新(升级)的方式
- tomcat错误(从ITEYE搬家而来)
- 多表查询、左右链接等
- AWS CodePipeline
- Vue基础概念,学习环境等
- spring MVC 访问静态资源报No handler mapping found for的解决(从ITEYE搬家过来的)
- Eclipse所有编码格式修改位置(项目、文件、css、sql、xml、jsp、html等)