Chinaunix首页 | 论坛 | 博客
  • 博客访问: 257411
  • 博文数量: 21
  • 博客积分: 1263
  • 博客等级: 准尉
  • 技术积分: 697
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-24 00:05
个人简介

专注于Answers Ranking, Answer Monitor和log处理。

文章分类
文章存档

2014年(5)

2012年(16)

分类: C/C++

2012-04-12 20:39:38

里面还有两个类,它们主要是把前面两次讲的内存分配器转换为符合STL标准的内存分配器,只是进行了封装并重载了几个运算符。

中的函数主要是在内存上初始化对象。它对于不同类型选择不同的方法以达到较高的效率。先看看这个文件的结构:


就按这个文件从上往下来看,先看uninitialized_copy:

  1. template <class _InputIter, class _ForwardIter>
  2. inline _ForwardIter
  3.   uninitialized_copy(_InputIter __first, _InputIter __last,
  4.                      _ForwardIter __result)
  5. {
  6.   return __uninitialized_copy(__first, __last, __result,
  7.                               __VALUE_TYPE(__result));
  8. }

  9. inline char* uninitialized_copy(const char* __first, const char* __last,
  10.                                 char* __result) {
  11.   memmove(__result, __first, __last - __first);
  12.   return __result + (__last - __first);
  13. }

  14. inline wchar_t*
  15. uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
  16.                    wchar_t* __result)
  17. {
  18.   memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
  19.   return __result + (__last - __first);
  20. }
对于char * 和wchar *直接使用的是memmove来进行复制的,而对于其余结构,调用的是__uninitialized_copy函数。再看看它的结构:

  1. // Valid if copy construction is equivalent to assignment, and if the
  2. // destructor is trivial.
  3. template <class _InputIter, class _ForwardIter>
  4. inline _ForwardIter
  5. __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  6.                          _ForwardIter __result,
  7.                          __true_type)
  8. {
  9.   return copy(__first, __last, __result);
  10. }

  11. template <class _InputIter, class _ForwardIter>
  12. _ForwardIter
  13. __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
  14.                          _ForwardIter __result,
  15.                          __false_type)
  16. {
  17.   _ForwardIter __cur = __result;
  18.   __STL_TRY {
  19.     for ( ; __first != __last; ++__first, ++__cur)
  20.       _Construct(&*__cur, *__first);
  21.     return __cur;
  22.   }
  23.   __STL_UNWIND(_Destroy(__result, __cur));
  24. }


  25. template <class _InputIter, class _ForwardIter, class _Tp>
  26. inline _ForwardIter
  27. __uninitialized_copy(_InputIter __first, _InputIter __last,
  28.                      _ForwardIter __result, _Tp*)
  29. {
  30.   typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;
  31.   return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());
  32. }
可以看到它同样使用了type traits编程方法。如果类型是POD的,那么OK,直接copy就行了,否则就需要逐个调用拷贝构造函数为它们构造对象。调用的就是 _Construct(&*__cur, *__first); 这个东西在stl_construct.h里己经讨论过了。

再看看 uninitialized_fill


  1. template <class _ForwardIter, class _Tp>
  2. inline void uninitialized_fill(_ForwardIter __first,
  3.                                _ForwardIter __last,
  4.                                const _Tp& __x)
  5. {
  6.   __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first));
  7. }
它调用的是inline void __uninitialized_fill,看看它们的结构:

  1. template <class _ForwardIter, class _Tp>
  2. inline void
  3. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last,
  4.                          const _Tp& __x, __true_type)
  5. {
  6.   fill(__first, __last, __x);
  7. }

  8. template <class _ForwardIter, class _Tp>
  9. void
  10. __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last,
  11.                          const _Tp& __x, __false_type)
  12. {
  13.   _ForwardIter __cur = __first;
  14.   __STL_TRY {
  15.     for ( ; __cur != __last; ++__cur)
  16.       _Construct(&*__cur, __x);
  17.   }
  18.   __STL_UNWIND(_Destroy(__first, __cur));
  19. }

  20. template <class _ForwardIter, class _Tp, class _Tp1>
  21. inline void __uninitialized_fill(_ForwardIter __first,
  22.                                  _ForwardIter __last, const _Tp& __x, _Tp1*)
  23. {
  24.   typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD;
  25.   __uninitialized_fill_aux(__first, __last, __x, _Is_POD());
  26.                    
  27. }
可以看到也是用的type traits编程技术。对于POD(plain old data : C++11对其定义进行了放宽)类型来说,用是的 fill(__first, __last, __x);来进行填充,而对于非POD类型,则与copy一样,用的是_construct构造。

uninitialized_copy和uninitialized_fill实现非常相似,作用也相似,唯一的区别就是copy是将原始对象一个一个复制过来,而fill则是将每一个块内存都是同一个对象进行构造。

而对于uninitialized_copy_n与uninitialized_fill_n与uninitialized_copy和uninitialized_fill有许多相似之外,这里不再表述。

下一次再看看auto_ptr的实现,auto_ptr在《STL源码剖析》里面好像没有讲到(至少我看目录没有找到)。



阅读(4649) | 评论(6) | 转发(1) |
给主人留下些什么吧!~~

重返人生2012-04-15 20:33:50

在<stl_uninitialized.h>中的函数主要是在内存上初始化对象。。。

☆彼岸★花开2012-04-15 20:28:45

不错啊~~多谢分享了~~~

桔色花朵2012-04-14 12:35:32

自己去网上找找吧,这个很少有人需要分析很深入的吧?你用得到?

夏冰软件2012-04-13 16:55:42

写的不错,支持一下

_Rayx2012-04-13 15:57:44

十七岁的回忆: 《STL源码剖析》没有的话,其他书籍里面呢???楼主知道嘛???.....
是说auto_ptr么?
应该没有专门讲这个的,因为这个东西并不太难,而且其实实际用得也很少。你可以看我下面分析。