前面我们使用了uninitialized_fill,来批量初始化某一段内存。

下面提供三个函数的实现代码,这三个代码的共同点是:

1.遇到错误,抛出异常

2.出现异常时,把之前构造的对象全部销毁

所以,这三个函数要么成功,要么无任何副作用。使用异常来通知使用者,所以在catch块中,处理完异常后要将异常再次向外抛出

  1. #ifndef MEMORY_HPP
  2. #define MEMORY_HPP
  3.  
  4. #include <iterator>
  5.  
  6. template <typename ForwIter, typename T>
  7. void uninitialized_fill(ForwIter beg, ForwIter end, const T & value)
  8. {
  9. typedef typename std::iterator_traits<ForwIter>::value_type VT;
  10. ForwIter save(beg); //备份beg的初始值
  11. try
  12. {
  13. for(; beg != end ; ++beg)
  14. {
  15. new (static_cast<void *>(&*beg))VT(value);
  16. }
  17. }
  18. catch(...) //抛出异常
  19. {
  20. for(; save != beg; ++save)
  21. {
  22. save->~VT(); //逐个进行析构
  23. }
  24. throw; //将catch的异常再次抛出
  25. }
  26. }
  27.  
  28. template <typename ForwIter, typename Size, typename T>
  29. void uninitialized_fill_n(ForwIter beg, Size num, const T & value)
  30. {
  31. typedef typename std::iterator_traits<ForwIter>::value_type VT;
  32. ForwIter save(beg);
  33. try
  34. {
  35. for(; num-- ; ++beg)
  36. {
  37. new (static_cast<void *>(&*beg))VT(value);
  38. }
  39. }
  40. catch(...)
  41. {
  42. for(; save != beg; ++save)
  43. {
  44. save->~VT();
  45. }
  46. throw;
  47. }
  48. }
  49.  
  50. template <typename InputIter, typename ForwIter>
  51. void uninitialized_copy(InputIter beg, InputIter end, ForwIter dest)
  52. {
  53. typedef typename std::iterator_traits<ForwIter>::value_type VT;
  54. ForwIter save(dest);
  55. try
  56. {
  57. for(; beg != end ; ++beg, ++dest)
  58. {
  59. new (static_cast<void *>(&*dest))VT(*beg);
  60. }
  61. }
  62. catch(...)
  63. {
  64. for(; save != dest; ++save)
  65. {
  66. save->~VT();
  67. }
  68. throw;
  69. }
  70. }
  71.  
  72. #endif /* MEMORY_HPP */

可以使用前面的代码自行测试。

标准库Allocator(三)uninitialized_fill等函数的实现的更多相关文章

  1. 标准库Allocator的使用(一)

    上一篇我们提到了new运算符以及它的工作步骤,其实无非是把两项工作独立出来: 1.申请原始内存 2.执行构造函数 delete也涉及了两个工作: 1.执行析构函数 2.释放原始内存 其实标准库提供了另 ...

  2. 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

    我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...

  3. Go标准库学习之OS常用函数

    1.OS基础操作 //获取主机名 os.Hostname() //获取当前目录 os.Getwd() //获取用户ID os.Getuid() //获取有效用户ID os.Geteuid() //获取 ...

  4. 【C标准库】详解feof函数与EOF

    创作不易,多多支持! 再说此函数之前,先来说一下EOF是什么 EOF,为End Of File的缩写,通常在文本的最后存在此字符表示资料结束. 在C语言中,或更精确地说成C标准函式库中表示文件结束符. ...

  5. C++标准库之vector(各函数及其使用全)

    原创作品,转载请注明出处:http://www.cnblogs.com/shrimp-can/p/5280566.html iterator类型: iterator:到value_type的访问,va ...

  6. c++标准库中的string常用函数总结《转》

    标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...

  7. Python 3标准库第三章

    时间过得很快,又是一周过去了,今天感觉迷迷糊糊的,不在状态,然后,下面开始我们的讲解,还是跟大家分享一下我自己的一些想法,第一.怎么讲了,就是各位如果有怀才不遇的想法,我感觉最好不要有这种想法;第二. ...

  8. 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset

    我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...

  9. 走进C标准库(6)——"string.h"中函数的实现memchr

    我写的memchr: void *memchr(const void *buf, char ch, unsigned count){ unsigned ; while(*(buf++) != ch & ...

随机推荐

  1. bzoj 1690: [Usaco2007 Dec]奶牛的旅行——分数规划+spfa判负环

    Description 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城 ...

  2. sqlmap注入一般步骤

    1. 找到注入点url2. sqlmap -u url -v 1--dbs 列出数据库或者 sqlmap -u url -v 1 --current-db 显示当前数据库3. sqlmap -u ur ...

  3. linux 内核库函数 【转】

    转自:http://blog.chinaunix.net/uid-20321537-id-1966892.html 当编写驱动程序时,一般情况下不能使用C标准库的函数.Linux内核也提供了与标准库函 ...

  4. Windows环境Vim编辑器如何执行Ruby代码

    1.下载 Ruby 1.8.5(2006-8-25) for Windows: 在网页http://www.rubychina.net/downloads/ 上找到  --〉Ruby on Windo ...

  5. python里如何计算大文件的md5

    在python3中,有了一个hashlib,可以用来计算md5,这里先给出一个简单的例子: import hashlib sstr="i love hanyu" print(has ...

  6. ubuntu16下安装telnet和opensshserver

    安装了虚拟机,使用的是ubuntu 16,server版本. 启动后发现没有telnet和ssh,就安装了(netstat -a|grep telnet). apt-get install openb ...

  7. TP5使用技巧

    1.fetchSql用于直接返回SQL而不是执行查询,适用于任何的CURD操作方法. 例如:$result = Db::table('think_user')->fetchSql(true)-& ...

  8. 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)

    J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...

  9. python实现无重复字符串的最长子串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...

  10. [TopCoder8600]MagicFingerprint

    题目大意: 定义magic(x)为将x按十进制顺序写下来,依次对相邻两个数写下差的绝对值,并去除前导0得到的新数. 若对得到的magic(x)重复进行多次magic,最后会变成一个一位数. 若最后变成 ...