STL源码解析-02配置器-02stl解析

*************************************************
 * STL中,将内存的申请与对象的构造分开进行,分别进行定义,具体来说,包含在两个文件中,<stl_construct.h>和<stl_alloc.h>。
 *
 * stl_construct.h:
 * construct:采用了placement new操作符。
 * destroy:一个泛化模板的实现,根据__type_traits中的has_trivial_destructor是__true_type还是__false_type,分别调用相应的偏特化版本。
 *          一个对char *的特化实现。
 *          一个对wchar_t*的特化实现。
 *          一个对T*的特化实现。
 *
 * stl_alloc.h:
 * 在STL中,考虑到小型区域可能造成的内存破碎问题,SGI设计了双层级配置器;
 * 第一级:__malloc_alloc_template,直接使用malloc()和free()。
 * 第二级:__default_alloc_template,如果配置区超过128bytes,调用第一级;如果小于,采用复杂的内存池进行。
 * 
 * 第一级的基本设计思想:
 * allocate:通过malloc进行内存分配,失败调用内部函数oom_allocate,在oom中不断的尝试释放、配置,如果指定了malloc_handler函数,执行该函数。
 * deallocate:直接调用free。
 * reallocate:调用realloc函数,分配失败时,与malloc的处理方式一样。
 *
 * 第二级的基本思想:
 * __default_alloc_template中维护着16个free-list,每个list管理的大小分别为:8,16,32,...,120,128,所以最后分配的都是8的倍数。
 * allocate:若n大于128byte,调用第一级;
 *           小于,找到round_up(向上对齐,是8的倍数)之后对应的list,如果list有节点,返回;
 *              如果没有,调用refill函数,从内存池中分配20个n大小的内存空间,将20这个大小挂在对应的list之下。
 * chunck_alloc:在refill中被调用,该函数是在内存池中分配空间给相应的list,实现的过程比较复杂。如果内存池的容量大于请求大小(n*size),直接分配;
 *         如果小于请求大小但是可以分配至少一个的空间,则返回最大能分配的内存地址;
 *         如果连一个的大小都不够,将内存池的空间挂到相应的list之下,重新申请空间,大小为原来的2倍+附件量,如申请空间成功,递归调用自己;
 *         如果失败,从size对应的list开始往后找,看其他LIST中有没有空间可以分配,若没有满足的,调用第一级的试一试,如果不行,第一级会抛异常。
 ************************************************************
 
***********************************************************
 * 内存基本处理工具
 * uninitialized_copy(InputIterator first, InputIterator last, ForeardIterator result):使用copy构造函数,将[first,last)范围内的每一个对象产生
 * 一个复制品,放进输出的范围。
 * uninitialized_fill(InputIteraot first, InputIterator last, const T&):对[first,last)范围内的每一个迭代器调用构造函数。
 * uninitialized_fill_n(InputIteraot first, Size n, const T&x):对[first,first+n)范围内的每一个迭代器调用构造函数。
 * **********************************************************
 
 
************************************************************
 *
 * Traits变成技法:
 * 在STL中,很多地方都用到了traits编程方式,他和模板的偏特化结合起来一起用,在迭代器,普通类型中都有traits的应用。
 * struct __true_type {};
 * struct __false_type {};
 *
 * template <class T>
 * struct __type_traits{
 *  typedef __false_type has_trivial_default_constructor;
 *  typedef __false_type has_trivial_copy_constructor;
 *  typedef __false_type has_trivial_assignment_operator;
 *  typedef __false_type has_trivial_destructor;
 *  typedef __false_type is_POD_type;           //POD:Plain Old Type,传统的C struct,必然拥有ctor/dtor/copy/assignment。
 * }
 *
 * 对于具体的int,long,double等类型可以特化实现该traits,定义与之相对应的typedef。
 * trait其实是对类型的一种说明,通过类型的某些属性,我们可以针对性的偏特化模板。
 * 如:
 *  template <class ForwardIterator, class T>
 *  inline void uninitialized_fill(ForwardIterator first, ForwardItertor last, const T& x)
 *  {
 *      __uninitialized_fill(first, last, x, value_type(x));
 *  }
 *
 *  template <class ForwardIterator, class T, class T1>
 *  inline void __uninitialized_fill(ForwardIterator first, ForwardItertor last, const T& x, T1*)
 *  {
 *      typedef typename __type_traits<T1>::is_POD_type is_POD;
 *      __uninitialized_fill_aux(first, last, x, is_POD);
 *  }
 *  //进行函数的偏特化
 *  template <class ForwardIterator, class T>
 *  inline void __uninitialized_fill_aux(ForwardIterator first, ForwardItertor last, const T& x, __true_type)
 *  {
 *      fill(first,last,x);
 *  }
 *
 *  template <class ForwardIterator, class T>
 *  inline void __uninitialized_fill_aux(ForwardIterator first, ForwardItertor last, const T& x, __false_type)
 *  {
 *      //
 *  }
 *  偏特化看中的是类型的不同,如果把__false_type和__true_type分别定义为ture和false的话,就没法应用函数的偏特化。
 *****************************************************************************************
posted @ 2011-12-02 14:57  magicdog  阅读(273)  评论(0)    收藏  举报