STL源代码剖析-06 stl_uninitialized.h

4683阅读 6评论2012-04-12 _Rayx
分类:C/C++

里面还有两个类,它们主要是把前面两次讲的内存分配器转换为符合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源码剖析》里面好像没有讲到(至少我看目录没有找到)。



上一篇:STL源代码剖析-05 stl_alloc.h(2)
下一篇:STL源代码剖析-07 memory 智能指针auto_ptr

文章评论