深度剖析空间配置器(三)内存处理函数

来源:互联网 发布:韩端机器人编程软件 编辑:程序博客网 时间:2024/06/07 11:29

空间配置器

主要分三个文件实现,我们已经介绍过第一个文件了(对象的构造和析构   http://blog.csdn.net/hj605635529/article/details/70238270),

第二个(http://blog.csdn.net/hj605635529/article/details/70238728  一二级配置器)

现在我们来介绍第三个文件 stl_uninitialized.h 这里定义了一些全局函数,用来填充(fill)或复制(copy)大块内存数据

uninitialized_copy(),uninitialized_copy_n(),uninitialized_fill(),uninitialized_fill_n()   (由函数名可知,是对未初始化空间的初始化操作,即通过复制或赋值的方式初始化未初始化的空间)

先学习 uninitiated_copy()

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. //stl source code(v3.3)  
  2. //defined in <stl_uninitialized.h>  
  3. inline char* uninitialized_copy(const char* __first, const char* __last, char* __result)   
  4. {  
  5.     memmove(__result, __first, __last - __first);  
  6.     return __result + (__last - __first);  //返回该连续区域的末尾  
  7. }  
  8.   
  9. inline wchar_t*   // typedef unsigned short wchar_t;  
  10. uninitialized_copy(const wchar_t* __first, const wchar_t* __last, wchar_t* __result)  
  11. {  
  12.     memmove(__result, __first, sizeof(wchar_t)* (__last - __first));  
  13.     return __result + (__last - __first);  
  14. }  
上面两个是对两种特化类型的处理,下面为泛化版本

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. template <class _InputIter, class _ForwardIter>  
  2. inline _ForwardIter  
  3. uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result)  
  4. {     
  5.     //根据数值型别决议出最佳效率的函数  
  6.     return __uninitialized_copy(__first, __last, __result, __VALUE_TYPE(__result));  
  7. }  
  8.   
  9. template <class _InputIter, class _ForwardIter, class _Tp>  
  10. inline _ForwardIter  
  11. __uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result, _Tp*)  
  12. {  
  13.     typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;   //判断数值型别  
  14.     //在C++中,我们把传统的C风格的struct叫做POD(Plain Old Data)对象  
  15.   
  16.     return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());  
  17. }  
  18.   
  19. //如果copy construction 和 operator = 等效(POD type),并且 destructor is trivial 的情况   
  20. template <class _InputIter, class _ForwardIter>  
  21. inline _ForwardIter  
  22. __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __true_type)  
  23. {  
  24.     /*针对POD对象,其二进制内容是可以随便复制的*/  
  25.     return copy(__first, __last, __result);  
  26.   
  27.     /*简化处理,详见<stl_algobase.h> 
  28.     inline _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) 
  29.     { 
  30.         memmove(__result, __first, sizeof(_Tp) * (__last - __first)); 
  31.         return __result + (__last - __first); 
  32.     } 
  33.     */  
  34. }  
  35.   
  36. /*如果copy construction 和 operator = 不等效,就需要调用 construct() 构造 */  
  37. template <class _InputIter, class _ForwardIter>  
  38. _ForwardIter  
  39. __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __false_type)  
  40. {  
  41.     _ForwardIter __cur = __result;  
  42.   
  43.     /*下面就是捕捉异常处理*/  
  44.     __STL_TRY{    //#define __STL_TRY  try  
  45.         for (; __first != __last; ++__first, ++__cur) //一个一个元素的构造,无法批量进行  
  46.         _Construct(&*__cur, *__first);   //每个对象都以其它对象为蓝本进行构造,使用的是 placement new  
  47.         return __cur;  
  48.     }  
  49.     /*commit or rollback:要么构造出所有必要元素, 
  50.     要么(当有任何一个 copy construct 失败时)不构造任何东西,保证所有对象都被析构*/  
  51.     __STL_UNWIND(_Destroy(__result, __cur));  
  52.     //#define __STL_UNMIND(action)  catch(...) { action; throw;}  
  53. }  
POD就是标量型别或传统的C struct 型别,POD 型别必然拥有 trivial ctor / dtor / copy / assignment 函数,因此我们可以对POD型别进行判断,从而决议出最有效率的初值填写手法

不难发现上面 uninitiated_copy() 后,返回的是指向 copy 后的区块末端。

uninitiated_copy_n() 则是向指定欲初始化空间初始化(复制)指定大小已初始化空间的指定值(有点拗口)。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. template <class _InputIter, class _Size, class _ForwardIter>  
  2. inline pair<_InputIter, _ForwardIter>  
  3. uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result)  
  4. {  
  5.     //最后一个形参判断迭代器 first 的类别  
  6.     return __uninitialized_copy_n(__first, __count, __result, __ITERATOR_CATEGORY(__first));  
  7. }  
  8.   
  9. //函数返回两个值,采用 pair 对组  
  10. //迭代器型别为支持随机存取的迭代器,涵盖所有指针运算能力,可以直接使用uninitialized_copy()进行复制  
  11. template <class _RandomAccessIter, class _Size, class _ForwardIter>  
  12. inline pair<_RandomAccessIter, _ForwardIter>  
  13. __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, _ForwardIter __result, random_access_iterator_tag)  
  14. {  
  15.     _RandomAccessIter __last = __first + __count;  
  16.     return pair<_RandomAccessIter, _ForwardIter>(__last, uninitialized_copy(__first, __last, __result));  
  17. }  
  18.   
  19. //迭代器为只读型别,所指的对象不允许外界改变  
  20. template <class _InputIter, class _Size, class _ForwardIter>  
  21. pair<_InputIter, _ForwardIter>  
  22. __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result, input_iterator_tag)  
  23. {  
  24.     /*针对输入范围内的每一个迭代器,函数会调用construct()函数产生迭代器所指对象的复制品, 
  25.     放置于输出范围的相应位置上*/  
  26.     _ForwardIter __cur = __result;  
  27.     __STL_TRY{          
  28.         for (; __count > 0; --__count, ++__first, ++__cur)  
  29.         _Construct(&*__cur, *__first);  
  30.         return pair<_InputIter, _ForwardIter>(__first, __cur);  
  31.     }  
  32.     __STL_UNWIND(_Destroy(__result, __cur));  
  33. }  
上面函数都是返回 pair 对组类型。其实就是返回两个值,一个是 “只读” 型别的迭代器(_InputIter),一个是允许 “写入型” 的迭代器(_ForwardIter)。
下面这个函数 uninitiated_fill() 和 uninitiated_copy() 操作很像,只不过前者是赋值,后者是复制。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. //迭代器类型为“写入型”。该函数的功能就是给迭代器指定范围内赋值  
  2. //具体实现过程参考函数 uninitialized_copy()  
  3. template <class _ForwardIter, class _Tp>  
  4. inline void uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x)  
  5. {  
  6.     __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first));  
  7. }  
  8.   
  9. //判断数值型别,同 uninitialized_copy()  
  10. template <class _ForwardIter, class _Tp, class _Tp1>  
  11. inline void __uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, _Tp1*)  
  12. {  
  13.     typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD;  
  14.     __uninitialized_fill_aux(__first, __last, __x, _Is_POD());  
  15. }  
  16.   
  17. template <class _ForwardIter, class _Tp>  
  18. inline void  
  19. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __true_type)  
  20. {  
  21.     fill(__first, __last, __x);  
  22.     /*简化处理,参见<stl_algobase.h> 
  23.     template <class _ForwardIter, class _Tp> 
  24.     void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value)  
  25.     { 
  26.         for ( ; __first != __last; ++__first) 
  27.             *__first = __value; 
  28.     } 
  29.     */  
  30. }  
  31.   
  32. template <class _ForwardIter, class _Tp>  
  33. void  
  34. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, const _Tp& __x, __false_type)  
  35. {  
  36.     _ForwardIter __cur = __first;  
  37.     __STL_TRY{  
  38.         for (; __cur != __last; ++__cur)  
  39.         _Construct(&*__cur, __x);  
  40.     }  
  41.     __STL_UNWIND(_Destroy(__first, __cur));  
  42. }  
下面的函数 uninitiated_fill_n() 则是向指定欲初始化空间初始化(赋值)指定大小空间的指定值。

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. template <class _ForwardIter, class _Size, class _Tp>  
  2. inline _ForwardIter  
  3. uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x)  
  4. {  
  5.     return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first));  
  6. }  
  7.   
  8. template <class _ForwardIter, class _Size, class _Tp, class _Tp1>  
  9. inline _ForwardIter  
  10. __uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*)  
  11. {  
  12.     typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD;  
  13.     return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());  
  14. }  
  15.   
  16. template <class _ForwardIter, class _Size, class _Tp>  
  17. _ForwardIter  
  18. __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __false_type)  
  19. {  
  20.     _ForwardIter __cur = __first;  
  21.     __STL_TRY{  
  22.         for (; __n > 0; --__n, ++__cur)  
  23.         _Construct(&*__cur, __x);  
  24.         return __cur;  
  25.     }  
  26.     __STL_UNWIND(_Destroy(__first, __cur));  
  27. }  
  28.   
  29. template <class _ForwardIter, class _Size, class _Tp>  
  30. inline _ForwardIter  
  31. __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __true_type)  
  32. {  
  33.     return fill_n(__first, __n, __x);  
  34.     /*简化处理,参见<stl_algobase.h> 
  35.     template <class _OutputIter, class _Size, class _Tp> 
  36.     _OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) 
  37.     { 
  38.         for ( ; __n > 0; --__n, ++__first) 
  39.             *__first = __value; 
  40.         return __first; 
  41.     } 
  42.     */  
  43. }  


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 防水台鞋跟太高怎么办 证件照头部比例过大怎么办 特岗照片传错了怎么办 打印报名表照片不显示怎么办 刚买的床有味道怎么办 雨刷器角度太小怎么办 四个月宝宝闹觉怎么办 怀孕六个月睡不好觉怎么办? 婴儿睡不好觉总是吵闹怎么办 婴儿鼻塞睡不好觉怎么办 玩英雄联盟鼠标变亮白怎么办 练芭蕾脚受伤了怎么办 高三了英语30分怎么办 要上高中了英语不好怎么办 高二了数学不好怎么办 高二函数不好怎么办啊 输乳怎么办腺病有什么妇症状 屁股上坐的发黑怎么办 车屁股撞了个洞怎么办 腰压迫的腿疼怎么办 肩胛提肌固定不住怎么办 胳膊粗后背肉多怎么办 2岁儿童 肋骨边缘外翻怎么办 5岁宝宝盆骨前倾怎么办 脖子弯了像驼背怎么办 都40周了还没生怎么办 股骨头坏死骨盆歪了怎么办 二胎侧切伤口疼怎么办 小月子盆骨酸痛怎么办 盆骨一边大一边小怎么办 快生了宫颈管长怎么办 想顺产 宫颈管长怎么办 腰和跨一样宽怎么办 脚后跟骨折手术后小腿变细怎么办 生完孩子骨盆错位怎么办 皮肤又黑又粗糙怎么办 翠研珠宝被坑了怎么办 领导是小人我该怎么办 微信二维码重置了怎么办 衣服有蝽的卵怎么办 人坐牢去了房贷怎么办