﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-lwch-随笔分类-STL</title><link>http://www.cppblog.com/lwch/category/19336.html</link><description>【QQ:510134884】【Email:&lt;a href="mailto:lwch748@gmail.com"&gt;lwch748@gmail.com&lt;/a&gt;】</description><language>zh-cn</language><lastBuildDate>Tue, 30 Apr 2013 12:57:36 GMT</lastBuildDate><pubDate>Tue, 30 Apr 2013 12:57:36 GMT</pubDate><ttl>60</ttl><item><title>QCore/Library说明文档</title><link>http://www.cppblog.com/lwch/archive/2013/04/30/199861.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Tue, 30 Apr 2013 12:24:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/04/30/199861.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/199861.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/04/30/199861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/199861.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/199861.html</trackback:ping><description><![CDATA[<p style="text-align: center"><span style="font-size:18pt"><strong>QCore/Library说明文档
</strong></span></p><p style="text-align: center">李文超
</p><p style="text-align: justify"></p><h1>前言
</h1><p>&nbsp;</p><p>QCore/Library是一套类STL的类库，它在标准库的范围内删去了不常用的heap、deque等结构（至少我是不常用的）。并为一些容器提供了一些特殊的接口，比如vector中的push_back_unique、add和add_unique等。
</p><p>
&nbsp;</p><p>Library主要分为六部分，内存调试相关、容器、算法、正则、IO和Graphic，每个模块都有各自的分工，他们之间的耦合度极低，几乎每个模块都可以拆出来独立使用，下面来分别介绍各个模块。
</p><p style="text-align: justify"></p><h1>内存调试
</h1><p>&nbsp;</p><p>我们知道，在C/C++中内存相关的东西是极难控制的，在使用不当时可能造成各种错误，轻则内存泄漏，重则程序崩溃。所以，在生产环境中我们必须通过一个有效的手段来管理好内存。当然，在小块内存频繁new、delete的过程中也会产生大量的内存碎片，从而导致可用内存数量越来越少。应此我们设计了一个内存池来控制小块内存的频繁new、delete，以及做到对内存泄漏的检测。
</p><p>
&nbsp;</p><p>在内存池的设计之初，我只是简单的设计出了可以使用的MemoryPool的最简版本，它包含一个大块内存的free_list和每个小块内存的chunk_list，当时足以应付大部分的需求，而且最初用的是<a href="http://vld.codeplex.com/">Visual Leak Detector</a>来检测内存泄漏。但随着时间的推移，想要自己检测内存泄漏的欲望越来越强烈，之后便有了一个use_list来保存内存块的释放情况。当时完成了这个patch之后，兴奋的跑了一下TestCase，然后的结果我想大家应该知道了，一路的飘红，到处是内存泄漏。
</p><p>
&nbsp;</p><p>经过一天的调试，实在无法容忍的情况下，我翻阅了MSDN，查到了dbghelp.dll中可以通过许多函数来获取调用堆栈，于是在此之下便生产出了CallStack模块。有了它之后你就可以在任意地方保存当前的调用堆栈了，真是十分方便。当然直到现在，它还只支持在Windows下调用堆栈的获取（稍后我会翻阅资料，实现一个like unix的版本，如果可能的话）。
</p><p>
&nbsp;</p><p>这里不过多的描述实现的细节，具体可以看<a href="http://www.cppblog.com/lwch/archive/2012/07/14/183420.html">http://www.cppblog.com/lwch/archive/2012/07/14/183420.html</a>和<a href="http://www.cppblog.com/lwch/archive/2013/01/19/197415.html">http://www.cppblog.com/lwch/archive/2013/01/19/197415.html</a>两篇文章。
</p><p>
&nbsp;</p><p>最后来看allocator，这里只是简单的为其包装了一层。
</p><p>
&nbsp;</p><p>template &lt;typename T&gt;
</p><p>class allocator
</p><p>{
</p><p>public:
</p><p>&nbsp; &nbsp; allocator()
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; allocator(const allocator&lt;T&gt;&amp;)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static T* allocate()
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return reinterpret_cast&lt;T*&gt;(pool-&gt;allocate(sizeof(T), free_handler));
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static T* allocate(size_t n)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return reinterpret_cast&lt;T*&gt;(pool-&gt;allocate(n * sizeof(T), free_handler));
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static void deallocate(T* p)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; pool-&gt;deallocate(p, sizeof(T));
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static void deallocate(T* p, size_t n)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; pool-&gt;deallocate(p, n * sizeof(T));
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static void deallocateWithSize(T* p, size_t n)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; pool-&gt;deallocate(p, n);
</p><p>&nbsp; &nbsp; }
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static T* reallocate(T* p, size_t old_size, size_t n)
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; MemoryPool* pool = getPool();
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return pool-&gt;reallocate(p, old_size, n * sizeof(T), free_handler);
</p><p>&nbsp; &nbsp; }
</p><p>public:
</p><p>&nbsp; &nbsp; static void(*free_handler)(size_t);
</p><p>
&nbsp;</p><p>&nbsp; &nbsp; static void set_handler(void(*h)(size_t))
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; free_handler = h;
</p><p>&nbsp; &nbsp; }
</p><p>protected:
</p><p>&nbsp; &nbsp; static MemoryPool* getPool()
</p><p>&nbsp; &nbsp; {
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; static MemoryPool pool;
</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return &amp;pool;
</p><p>&nbsp; &nbsp; }
</p><p>};
</p><p>
&nbsp;</p><p>template &lt;typename T&gt;
</p><p>void (*allocator&lt;T&gt;::free_handler)(size_t) = 0;
</p><p style="text-align: justify"></p><h1>容器
</h1><p>&nbsp;</p><p>    容器占了Library的大部分，容器的作用是用来存储对象的，容器分为线性和非线性两种。线性的容器有vector、list、string以及用它们作为容器实现的queue、stack四种，非线性的则有rbtree、hashtable以及用它们作为容器实现的set、map、hashset、hashmap六种。对于每种容器，都必须定义出它的value_type、pointer、reference、const_reference、size_type、distance_type、const_iterator、const_reverse_iterator、iterator、reverse_iterator的类型。
</p><p>
&nbsp;</p><p>    所有容器必须包含以下几个接口：size（获取容器内元素个数）、clear（清空容器）、begin（获取[first,last)区间中的first迭代器）、end（获取[first,last)区间中的last迭代器）、rbegin（获取反向的first迭代器）、rend（获取反向的last迭代器）。
</p><p style="text-align: justify"></p><h2>traits
</h2><p>&nbsp;</p><p>    traits是一种萃取技术，通过它你可以获取某种类型的一些特性，比如是否含有默认构造函数、拷贝构造函数等。
</p><p style="text-align: justify"></p><h3>__type_traits
</h3><p>&nbsp;</p><p>    __type_traits用于萃取出某种类型的一些特性，它的原型如下
</p><p>
&nbsp;</p><p>    template &lt;typename T&gt;
</p><p>    struct __type_traits
</p><p>    {
</p><p>&nbsp; &nbsp; typedef __true_type  has_default_construct;
</p><p>&nbsp; &nbsp; typedef __true_type  has_copy_construct;
</p><p>&nbsp; &nbsp; typedef __true_type  has_assign_operator;
</p><p>&nbsp; &nbsp; typedef __true_type  has_destruct;
</p><p>&nbsp; &nbsp; typedef __false_type is_POD;
</p><p>    };
</p><p>    通过特例化，可以定义出所有类型的这些属性，比如char
</p><p>
&nbsp;</p><p>    template &lt;&gt;
</p><p>    struct __type_traits&lt;char&gt;
</p><p>    {
</p><p>&nbsp; &nbsp; typedef __true_type  has_default_construct;
</p><p>&nbsp; &nbsp; typedef __true_type  has_copy_construct;
</p><p>&nbsp; &nbsp; typedef __true_type  has_assign_operator;
</p><p>&nbsp; &nbsp; typedef __false_type has_destruct;
</p><p>&nbsp; &nbsp; typedef __true_type  is_POD;
</p><p>    };
</p><p style="text-align: justify"></p><h3>__container_traits
</h3><p>&nbsp;</p><p>    __container_traits用于萃取出容器的特性，如上文所说的value_type等特性，它的代码很简单
</p><p>
&nbsp;</p><p>    template &lt;typename T&gt;
</p><p>    struct __container_traits
</p><p>    {
</p><p>&nbsp; &nbsp; typedef typename T::value_type       value_type;
</p><p>&nbsp; &nbsp; typedef typename T::pointer          pointer;
</p><p>&nbsp; &nbsp; typedef typename T::reference        reference;
</p><p>&nbsp; &nbsp; typedef typename T::const_reference  const_reference;
</p><p>&nbsp; &nbsp; typedef typename T::size_type        size_type;
</p><p>&nbsp; &nbsp; typedef typename T::distance_type    distance_type;
</p><p>&nbsp; &nbsp; typedef typename T::const_iterator   const_iterator;
</p><p>&nbsp; &nbsp; typedef typename T::const_reverse_iterator const_reverse_iterator;
</p><p>&nbsp; &nbsp; typedef typename T::iterator         iterator;
</p><p>&nbsp; &nbsp; typedef typename T::reverse_iterator reverse_iterator;
</p><p>    };
</p><p style="text-align: justify"></p><h3>char_traits
</h3><p>&nbsp;</p><p>    char_traits定义了一些对于Char的操作，包括assign（赋值）、eq（相等）、lt（小于）、compare（比较两个字符串的大小）、length（获取字符串的长度）、move（移动）、copy（拷贝）、assign（字符串赋值）、eof（结束符），它的<a href="../Source/QCore/Library/char_traits.h">代码</a>比较简洁，这里不做说明。
</p><p style="text-align: justify"></p><h2>type_compare
</h2><p>&nbsp;</p><p>    type_compare用于对两种类型做运行时的匹配，判断所给定的两种类型是否相同。同样通过特例化技术可以很轻松的实现它的<a href="../Source/QCore/Library/traits.h">代码</a>。
</p><p style="text-align: justify"></p><h2>迭代器
</h2><p>&nbsp;</p><p>    迭代器类是一种类似于smart pointer的东西，一般的它都会支持前置和后置的++和--操作，有一些特殊的迭代器同样支持+=和-=操作。当然作为一种smart pointer少不了的是-&gt;和*操作，而对于比较操作，则比较的是迭代器所保存的值。
</p><p>
&nbsp;</p><p>    迭代器分为bidirectional_iterator和random_access_iterator两种类型，前者只支持++和--操作而后者支持+和-运算符，之所以会定义出这两种类型是为了提高算法的速度。对于一个迭代器来说同样需要定义value_type、distance_type、pointer、reference、const_pointer、const_reference的类型。
</p><p>
&nbsp;</p><p style="text-align: justify"></p><h2>反向迭代器
</h2><p>&nbsp;</p><p>    反向迭代器与正向的正好相反，应此我们可以类似的定义它的++为正向迭代器的--等运算符
</p><p style="text-align: justify"></p><h2>iterator_traits
</h2><p>&nbsp;</p><p>    iterator_traits用于萃取出迭代器的所有特性，应此它比较简单
</p><p>
&nbsp;</p><p>    template &lt;typename Iterator&gt;
</p><p>    struct iterator_traits
</p><p>    {
</p><p>&nbsp; &nbsp; typedef typename Iterator::value_type      value_type;
</p><p>&nbsp; &nbsp; typedef typename Iterator::distance_type   distance_type;
</p><p>&nbsp; &nbsp; typedef typename Iterator::pointer         pointer;
</p><p>&nbsp; &nbsp; typedef typename Iterator::reference       reference;
</p><p>&nbsp; &nbsp; typedef typename Iterator::const_pointer   const_pointer;
</p><p>&nbsp; &nbsp; typedef typename Iterator::const_reference const_reference;
</p><p>    };
</p><p style="text-align: justify"></p><h2>vector
</h2><p>&nbsp;</p><p>vector是一种比较常用的容器，它的内部是一个连续的内存块，应此它有两个接口分别用于获取内存块已使用的大小和容器的大小，它们是size和capacity，同样它也有一个reserve接口来调整它的容量。由于vector的内部是连续的，应此它只允许从后面插入元素，所以它有push_back、push_back_unique和pop_back方法。当然为了作为queue的容器，我还为其增加了pop_front方法用于删除前端的元素。insert和erase用于在某个地方插入和删除元素，add和add_unique用于插入另一个vector里的内容，而unique则会将容器内重复的元素删除。
</p><p>
&nbsp;</p><p>当然vector可以像数组一样的使用，它支持方括号的运算符与at接口来获取某个位置上的元素值。
</p><p>
&nbsp;</p><p>vector容器就先介绍到这里，它的代码你可以在<a href="../Source/QCore/Library/vector.h">QCore/Library/vector.h</a>中找到。
</p><p style="text-align: justify"></p><h2>list
</h2><p>&nbsp;</p><p>list的内部则是一个双向的链表，应此它在删除前端的元素时会比vector快很多，它的接口基本跟vector相同，这里就不做过多的介绍了。由于vector是内存连续的，所以它可以直接通过索引来访问某个元素，而list是一个双向的链表，应此通过制定索引去访问某个元素时会先看这个索引的值是否小于list长度的一半来决定是从list的头部遍历还是从list的尾部遍历，它的代码你可以在<a href="../Source/QCore/Library/list.h">QCore/Library/list.h</a>中找到。
</p><p style="text-align: justify"></p><h2>queue和stack
</h2><p>&nbsp;</p><p>queue是一种FIFO（先进先出）的结构，应此我们建议使用list作为它的容器，通过list的push_back和pop_front可以使代码变的高效。它拥有front和back方法来获取队列中队头和队尾的元素值，同样在插入队列时，你可以不加选择的直接插入或是插入一个不重复的值。
</p><p>
&nbsp;</p><p>stack是一种FILO（先进后出）的结构，同样它拥有push、push_unique和pop方法以及top和bottom方法用于获取栈顶端和底部的元素值。
</p><p>
&nbsp;</p><p>对于这两种结构的代码，你可以在<a href="../Source/QCore/Library/queue.h">QCore/Library/queue.h</a>和<a href="../Source/QCore/Library/stack.h">QCore/Library/stack.h</a>中找到。
</p><p style="text-align: justify"></p><h2>rbtree
</h2><p>&nbsp;</p><p>rbtree（红黑树）是一棵自平衡的二叉查找树，应此它拥有较高的查找效率，红黑树有以下5条性质
</p><p>
&nbsp;</p><p>性质1. 节点是红色或黑色。
</p><p>性质2. 根节点是黑色。
</p><p>性质3 每个叶节点是黑色的。
</p><p>性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
</p><p>性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
</p><p><strong>以上摘自百度百科
</strong></p><p>
&nbsp;</p><p>对于红黑树的每个节点，它都拥有它的key和value，当然我们是按照节点的key来排序的（废话）。红黑树拥有insert_equal和insert_unique方法分别用于插入一个节点，前者允许待插入节点的key已存在于这棵树中，而后者在插入时并不允许这个节点的key已存在于这棵树中，应此它的返回值则是一个二元的。erase方法则提供了对于树中某个节点的删除操作，可以通过迭代器或某个key值来删除其中的节点。
</p><p>
&nbsp;</p><p>由于红黑树是一棵二叉查找树，应此它应该具备find方法，用于在树中查找某个节点，它返回的则是指向这个节点的一个迭代器。由于红黑树是有序的，应此可以通过maximum和minimum方法得到其中的最大和最小值。通过lower_bound和upper_bound可以得到属于某个key的[first,last]区间，equal_range就是干这个活的，count方法可以得到某个key所对应的节点数。
</p><p>
&nbsp;</p><p>rbtree就先介绍到这里，稍后我会在博客中继续更新提供更完整的实现方法，它的代码你可以在<a href="../Source/QCore/Library/rbtree.h">QCore/Library/rbtree.h</a>中找到。
</p><p style="text-align: justify"></p><h2>set和map
</h2><p>&nbsp;</p><p>set是一种集合的结构，应此在集合中是不允许有重复的元素的，set是以rbtree作为容器的。应此它的insert方法对应于rbtree的insert_unique方法，同样rbtree所具备的接口set也同样拥有，set的key_type与value_type相同，都是给定的类型。
</p><p>
&nbsp;</p><p>map则是一种key-value的directory结构，应此它的key是不允许重复的，map同样是以rbtree作为容器的。应此它的insert方法同样对应于rbtree的insert_unique方法，在map中除了rbtree的maximum、minimum、lower_bound、upper_bound、equal_range和count没有之外其他接口基本全都拥有，map的key_type是给定的类型，而value_type则是一个以Key和T组成的二元组。
</p><p>
&nbsp;</p><p>对于这两种结构的代码，你可以在<a href="../Source/QCore/Library/set.h">QCore/Library/set.h</a>和<a href="../Source/QCore/Library/map.h">QCore/Library/map.h</a>中找到。
</p><p style="text-align: justify"></p><h2>hashtable
</h2><p>&nbsp;</p><p>hashtable是一种哈希结构，应此它的元素查找和插入是非常快的。在这里我用的是吊桶法来处理元素插入时的冲突，当吊桶长度过长（默认是11个元素）时，会将桶的大小翻一倍然后重建整个hashtable以提高hashtable中元素的查找速度。
</p><p>
&nbsp;</p><p>同样的在hashtable中有insert_equal和insert_unique来分别插入允许相同和不同的元素，当遇到一个已有的元素时会将这个元素插入到第一个与它值相同的节点后面，这样做的好处是可以简单的实现equal_range方法。同时hashtable拥有value方法用于通过一个指定的key来查找到它对应的值，find方法则是用来查找一个key所对应的迭代器的。同样的hashtable也拥有count方法来获取某个key所对应的值的个数，maximum和minimum则是用来获取最大值和最小值的。
</p><p>
&nbsp;</p><p>hashtable的代码，你可以在<a href="../Source/QCore/Library/hashtable.h">QCore/Library/hashtable.h</a>中找到。
</p><p style="text-align: justify"></p><h2>hashset和hashmap
</h2><p>&nbsp;</p><p>hashset和hashmap基本与set和map相同，这里不过多做介绍，关于它们的代码，你可以在<a href="../Source/QCore/Library/hashset.h">QCore/Library/hashset.h</a>和<a href="../Source/QCore/Library/hashmap.h">QCore/Library/hashmap.h</a>中找到。
</p><p style="text-align: justify"></p><h2>basic_string
</h2><p>&nbsp;</p><p>basic_string的实现方式基本和vector差不多，为了提高效率，在所有的插入操作中若新的长度的一倍小于一个定长（默认是512）字节时会申请新长度的一倍作为容器的容量。
</p><p>
&nbsp;</p><p>与vector不同的是basic_string拥有c_str和data方法用于获取字符指针，append方法往字符串尾部链接另一个字符串，assign方法给字符串赋值，find方法查找到第一个指定的字符串的位置，substr则用来获取字符串中一部分的内容。
</p><p>
&nbsp;</p><p>在basic_string中也有format的静态方法来生成一个指定形式的字符串，其他用法基本与vecotr相同。它的代码，你可以在<a href="../Source/QCore/Library/string.h">QCore/Library/string.h</a>中找到。
</p><p style="text-align: justify"></p><h2>本章小结
</h2><p>&nbsp;</p><p>上面介绍了所有的容器的接口和使用方法，以及在实现方式上的一些技巧。希望通过上面的介绍，读者们能够体会到STL为什么需要这么去设计、这么设计的好处是什么。
</p><p>
&nbsp;</p><p>在我后来做regex的过程中，我深刻的体会到，选用一个合适的数据结构可以给代码的运行效率带来非常大的提升。比如给定NFA某个状态，需要找出所有从这个状态出发的边，之前使用的是map结构来保存从某个状态出发边的vector，之后发现遍历的速度非常缓慢，在换成hashmap之后，速度有显著的提升。应此在实际编程过程中，选用一个合适的数据结构显得尤为重要。
</p><p>
&nbsp;</p><p>在使用线性结构时，一般在小数据量或不平凡插入或删除数据的情况下，选用vector作为容器会更快一些。而在需要平凡插入或删除数据的场合下，选用list作为容器会有更优异的结果。需要保持元素唯一性的情况下，我会优先选用set作为容器，而在数据量非常大的情况下，就会使用hashset来代替set。map则如它的名字那样，适用于key-value的场合，而hashmap在数据量非常大的情况下使用。
</p><p style="text-align: justify"></p><h1>算法
</h1><p>&nbsp;</p><p>    min和max函数分别用于求取最小值和最大值，fill_n用来填充若干个对象的值。copy_backward用来从后往前拷贝值。distance用来求给定区间[first, last)的长度。search用于在给定范围[first1, last1)内查找符合序列[first2, last2)集合的值。swap和iterator_swap分别用于交换两个值和两个迭代器指向的值。sort用于将指定范围[first, last)内的值排序，find用于在指定范围[first, last)内查找指定的值。toArray用于将指定范围[first, last)内的值转换为内存连续的数组，compareArray则用于比较两个数组内的值的个数和值是否相同。
</p><p>
&nbsp;</p><p>    具体的实现代码，你可以在<a href="../Source/QCore/Library/algo.h">QCore/Library/algo.h</a>中找到。
</p><p style="text-align: justify"></p><h1>正则
</h1><p>&nbsp;</p><p>    通过重载+（相加）、-、|、+（前置）、*(前置）、!以及opt函数来生成正则表达式的&#949;-NFA，然后通过buildDFA函数生成DFA。通过parse和match可分析给定的字符串是否符合这个正则表达式，parse从头开始跑DFA看这个字符串的开头是否有符合这个正则表达式的字符串，而match则会找[first, last)区间内符合这个正则表达式的第一个字符串的相关结果。
</p><p>
&nbsp;</p><p>    具体的实现方法，你可以看<a href="http://www.cppblog.com/lwch/archive/2013/02/15/197848.html">http://www.cppblog.com/lwch/archive/2013/02/15/197848.html</a>和<a href="http://www.cppblog.com/lwch/archive/2013/02/23/198043.html">http://www.cppblog.com/lwch/archive/2013/02/23/198043.html</a>两篇文章，而代码则可在<a href="../Source/QCore/Library/regex/regex.h">QCore/Library/regex/regex.h</a>中找到。
</p><p style="text-align: justify"></p><h1>IO
</h1><p>&nbsp;</p><p>IO模块包含文件IO和标准输入输出IO，首先有两个基类分别是basic_istream和basic_ostream分别作为输入和输出stream的基类,其中分别定义了运算符&gt;&gt;和&lt;&lt;，通过这两个运算符可以直观的看到是从stream输出到变量或是从变量输入到stream中。之后有stdstream_basic和fstream_basic都继承自basic_istream和basic_ostream分别作为basic_stdstream和basic_fstream的基类，它们都有open、size、tell、seek、read、write和flush方法，它们都是对底层C函数的一些封装。而在下一层的basic_stdstream和basic_fstream中则实现了运算符&gt;&gt;和&lt;&lt;的所有重载，这样做的好处是可以使代码更有条理性，并方便阅读。
</p><p>
&nbsp;</p><p>对于标准输入输出流来说，实际上是对stdin、stdout、stderr的一些封装，当然里面也有一些比较特殊的接口，比如setColor（用于设置输入输出流的字体颜色）以及一些颜色相关的函数。
</p><p>
&nbsp;</p><p>对于fstream来说它是针对所有文件的，应此它会多一个readAll接口用于一次性的读出这个文件的所有内容，为了节省频繁读写磁盘所造成的性能损耗，我们给它定义了两个buffer用来做cache，当你要写入文件时，它并不是马上就直接往磁盘里写的，而会加到buffer当中，当达到一个预值时才真正的写入到磁盘。
</p><p>那么IO模块就先介绍到这里了，它们的代码你可以在<a href="../Source/QCore/Library/ios.h">QCore/Library/ios.h</a>、<a href="../Source/QCore/Library/istream.h">QCore/Library/istream.h</a>、<a href="../Source/QCore/Library/ostream.h">QCore/Library/ostream.h</a>、<a href="../Source/QCore/Library/fstream.h">QCore/Library/fstream.h</a>、<a href="../Source/QCore/Library/stdstream.h">QCore/Library/stdstream.h</a>、<a href="../Source/QCore/Library/iostream.h">QCore/Library/iostream.h</a>和<a href="../Source/QCore/Library/iostream.cpp">QCore/Library/iostream.cpp</a>中找到。
</p><p style="text-align: justify"></p><h1>结束
</h1><p>&nbsp;</p><p>上文介绍了大部分模块的实现过程与实现过程中的心得，让我们来按照顺序回顾一下。
</p><p>
&nbsp;</p><p>首先介绍了内存池的实现过程，以及在实现过程中遇到的一些问题，比如如何检测内存泄漏、如何获取调用堆栈等。
</p><p>
&nbsp;</p><p>然后介绍了traits技术，它是用来萃取出一些特性用的，通过traits技术你可以得到一个类型是否为POD是否有默认构造函数等特性。而__container_traits则萃取出了容器的一些特性，比如值类型等等。通过char_traits我们得到了一些关于字符串的操作，比如求字符串的长度等。
</p><p>
&nbsp;</p><p>之后又通过特例化，我们实现了一种比较两个变量类型是否相同的手段。
</p><p>
&nbsp;</p><p>接下来我们介绍了迭代器和反向迭代器，它们是一种类似于smart pointer的东西，我们可以通过一个[first, last]前闭后开区间来表示一个容器内的所有元素。然后我们通过iterator_traits萃取出了迭代器的一些特性，比如值类型等。
</p><p>
&nbsp;</p><p>最后我们介绍了所有比较常用的容器，以及在某些场合下应该使用哪种容器来达到高效的目的。比如在数据量较大时使用hashset要比使用set在插入和查找速度要更快一些，而且时间负责度更稳定一些。
</p><p>
&nbsp;</p><p>之后我们又介绍了一些常用算法，通过这些算法足以解决一些简单的问题。比如排序和求取一个范围[first, last]的长度等。
</p><p>
&nbsp;</p><p>在正则这一章中，介绍了我们是如何通过一些运算符的重载来构造出某个正则表达式的状态机的，以及如何通过运行这些状态机来分析给定的字符串。
</p><p>
&nbsp;</p><p>最后介绍了IO模块，其中分为标准输入输出流和文件流，通过重载&lt;&lt;和&gt;&gt;运算符，可以直观的看到是从流中讲内容输入到一个变量或是从一个变量中讲内容输入到流中。
</p><p>
&nbsp;</p><p>希望通过本文可使读者体会到作者在设计这个库的时候所考虑的问题，以及对这个库有一个大概的认识，稍后我会在我的<a href="http://www.cppblog.com/lwch">博客</a>中补齐所有没有介绍过的模块是如何实现的。
</p><p style="text-align: justify"></p><h1>修改记录
</h1><p>&nbsp;</p><p>2013.4.23第一次编写
</p><p>2013.4.24添加容器的说明
</p><p>2013.4.25添加hashtable、hashset、hashmap和basic_string结构的说明
</p><p>2013.4.28添加算法和正则的说明
</p><p>2013.4.30添加IO的说明，完结此文</p><img src ="http://www.cppblog.com/lwch/aggbug/199861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-04-30 20:24 <a href="http://www.cppblog.com/lwch/archive/2013/04/30/199861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之内存池V2</title><link>http://www.cppblog.com/lwch/archive/2013/01/19/197415.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 19 Jan 2013 12:09:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2013/01/19/197415.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/197415.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2013/01/19/197415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/197415.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/197415.html</trackback:ping><description><![CDATA[在<a href="http://www.cppblog.com/lwch/archive/2012/07/14/183420.html" target="_blank">上一篇中</a>我们已经实现了一个简单的内存池，可以申请更大块的内存块来减少申请小块内存块时产生的内存碎片。<br />
<br />
在本篇中，我们需要为其加入内存泄漏的检测代码，以此来检测代码编写过程中的疏忽带来的内存泄漏。（callstack的显示暂时仅支持Windows）<br />
<br />
<strong>一、内存泄漏检测</strong><br />
首先，改写obj和block结构，在obj中加入一个域released表示这个chunk是否被释放<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;obj<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;released;<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #0000FF; ">#if</span>&nbsp;defined(WIN32)&nbsp;&amp;&amp;&nbsp;!defined(__MINGW32__)&nbsp;&amp;&amp;&nbsp;!defined(__CYGWIN__)&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Only&nbsp;windows&nbsp;can&nbsp;get&nbsp;callstack</span><br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;CALLSTACK_MAX_DEPTH&nbsp;30<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UINT_PTR&nbsp;&nbsp;callStack[CALLSTACK_MAX_DEPTH];<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwCallStackDepth;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Real&nbsp;depth</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #008000; "></span><span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">11</span>&nbsp;<br />
<span style="color: #008080; ">12</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next;<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<span style="color: #008080; ">15</span>&nbsp;<br />
<span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;block<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;&nbsp;&nbsp;&nbsp;next;<br />
<span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data;<br />
<span style="color: #008080; ">20</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_type&nbsp;size;<br />
<span style="color: #008080; ">22</span>&nbsp;<span style="color: #0000FF; ">#if</span>&nbsp;defined(WIN32)&nbsp;&amp;&amp;&nbsp;!defined(__MINGW32__)&nbsp;&amp;&amp;&nbsp;!defined(__CYGWIN__)<br />
<span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UINT_PTR&nbsp;&nbsp;callStack[CALLSTACK_MAX_DEPTH];<br />
<span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwCallStackDepth;<br />
<span style="color: #008080; ">25</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">26</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
其中的callstack部分将在下一节中介绍<br />
<br />
然后，我们增加一个结构<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;use<br />
<span style="color: #008080; ">3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;data;<br />
<span style="color: #008080; ">5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;use*&nbsp;next;<br />
<span style="color: #008080; ">6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<span style="color: #008080; ">7</span>&nbsp;<span style="color: #0000FF; ">#endif</span></div>
其中data域指向了一块分配出去的小内存块，next域形成了一张链表。<br />
<br />
然后，我们添加一个成员变量来保存这张链表，以及一个函数来将一个chunk插入这张链表<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->#ifdef&nbsp;_DEBUG<br />
&nbsp;&nbsp;&nbsp;&nbsp;use*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;use_list;<br />
<span style="color: #0000FF; ">#endif</span><br />
<br />
#ifdef&nbsp;_DEBUG<br />
inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;MemoryPool::addUseInfo(obj*&nbsp;ptr)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;use*&nbsp;p&nbsp;=&nbsp;(use*)malloc(<span style="color: #0000FF; ">sizeof</span>(use));<br />
&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;data&nbsp;=&nbsp;ptr;<br />
&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;next&nbsp;=&nbsp;use_list;<br />
&nbsp;&nbsp;&nbsp;&nbsp;use_list&nbsp;=&nbsp;p;<br />
}<br />
<span style="color: #0000ff; ">#endif</span></div>
<br />
然后，我们来改写refill函数使其在分配内存块时打上released标记，并将每个分配的内存块记录下来<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;MemoryPool::refill(<span style="color: #0000FF; ">int</span>&nbsp;i,&nbsp;<span style="color: #0000FF; ">void</span>(*h)(size_type))<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;count&nbsp;=&nbsp;20;<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;preSize&nbsp;=&nbsp;(i&nbsp;+&nbsp;1)&nbsp;*&nbsp;ALIGN&nbsp;+&nbsp;headerSize;<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;p&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(preSize&nbsp;*&nbsp;count);<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(p&nbsp;==&nbsp;0)<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h(preSize&nbsp;*&nbsp;count);<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(preSize&nbsp;*&nbsp;count);<br />
<span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;pBlock&nbsp;=&nbsp;(block*)malloc(<span style="color: #0000FF; ">sizeof</span>(block));<br />
<span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(pBlock&nbsp;==&nbsp;0)<br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h(<span style="color: #0000FF; ">sizeof</span>(block));<br />
<span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock&nbsp;=&nbsp;(block*)malloc(<span style="color: #0000FF; ">sizeof</span>(block));<br />
<span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock-&gt;data&nbsp;=&nbsp;p;<br />
<span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock-&gt;next&nbsp;=&nbsp;free_list;<br />
<span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free_list&nbsp;=&nbsp;pBlock;<br />
<span style="color: #008080; ">20</span>&nbsp;<br />
<span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;current&nbsp;=&nbsp;(obj*)p;<br />
<span style="color: #008080; ">22</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addUseInfo(current);<br />
<span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current-&gt;released&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>;<br />
<span style="color: #008080; ">25</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;(obj*)((<span style="color: #0000FF; ">char</span>*)current&nbsp;+&nbsp;preSize);<br />
<span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;count&nbsp;-&nbsp;1;&nbsp;++j)<br />
<span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">29</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addUseInfo(current);<br />
<span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current-&gt;released&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br />
<span style="color: #008080; ">32</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current-&gt;next&nbsp;=&nbsp;chunk_list[i];<br />
<span style="color: #008080; ">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;current;<br />
<span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;(obj*)((<span style="color: #0000FF; ">char</span>*)current&nbsp;+&nbsp;preSize);<br />
<span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(<span style="color: #0000FF; ">char</span>*)p&nbsp;+&nbsp;headerSize;<br />
<span style="color: #008080; ">38</span>&nbsp;}</div>
其中的headerSize跟callstack有关，将在下一节中介绍。<br />
<br />
当然，在deallocate时要将此内存块的released标记打为true<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;MemoryPool::deallocate(<span style="color: #0000FF; ">void</span>*&nbsp;p,&nbsp;size_type&nbsp;n)<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(p&nbsp;==&nbsp;0)&nbsp;<span style="color: #0000FF; ">return</span>;<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;&gt;&nbsp;MAX_BYTES)<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;INDEX(ROUND_UP(n));<br />
<span style="color: #008080; ">10</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)p&nbsp;-&nbsp;(<span style="color: #0000FF; ">int</span>)headerSize;<br />
<span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;ptr&nbsp;=&nbsp;reinterpret_cast&lt;obj*&gt;(p);<br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(ptr-&gt;released)&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;error&lt;<span style="color: #0000FF; ">char</span>*&gt;("chunk&nbsp;has&nbsp;already&nbsp;released",&nbsp;__FILE__,&nbsp;__LINE__);<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr-&gt;released&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br />
<span style="color: #008080; ">15</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reinterpret_cast&lt;obj*&gt;(p)-&gt;next&nbsp;=&nbsp;chunk_list[i];<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;reinterpret_cast&lt;obj*&gt;(p);<br />
<span style="color: #008080; ">18</span>&nbsp;}</div>
<br />
OK，现在已经有模有样了，可以松口气了。接下来是最重要的部分，在MemoryPool析构时检测这个Pool内的use_list中是否有chunk的released标记为true（内存泄漏了）<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;MemoryPool::~MemoryPool()<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;#ifdef&nbsp;_DEBUG<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(use_list)<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;use&nbsp;*ptr&nbsp;=&nbsp;use_list,&nbsp;*next&nbsp;=&nbsp;use_list-&gt;next;<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!ptr-&gt;data-&gt;released)<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;pObj&nbsp;=&nbsp;ptr-&gt;data;<br />
<span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console::SetColor(<span style="color: #0000FF; ">true</span>,&nbsp;<span style="color: #0000FF; ">false</span>,&nbsp;<span style="color: #0000FF; ">false</span>,&nbsp;<span style="color: #0000FF; ">true</span>);<br />
<span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;error&lt;<span style="color: #0000FF; ">char</span>*&gt;("chunk&nbsp;leaked",&nbsp;__FILE__,&nbsp;__LINE__);<br />
<span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(ptr);<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;use_list&nbsp;=&nbsp;next;<br />
<span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">16</span>&nbsp;<span style="color: #0000FF; ">#endif</span><br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear();<br />
<span style="color: #008080; ">18</span>&nbsp;}</div>
其实说来也容易，只需要检测每个chunk的released标记是否为true就行了，而最后的clear函数是以前析构函数的代码，用来释放所有申请的block和大块的chunk。<br />
<br />
OK，现在我们已经可以检测出没有被deallocate的chunk了。<br />
<br />
<strong>二、callstack</strong><br />
首先，我们先来看一个Windows API，&#8220;<a href="http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb204633(v=vs.85).aspx" target="_blank">CaptureStackBackTrace</a>&#8221;这个API通过传入的一个数组来得到一组地址。当然有这个API并不够，我们还需要知道是哪个文件的第几行。&#8220;<a href="http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681344(v=vs.85).aspx" target="_blank">SymGetSymFromAddr64</a>&#8221;这个API用来获取某个地址对应的函数名，&#8220;<a href="http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms681330(v=vs.85).aspx" target="_blank">SymGetLineFromAddr64</a>&#8221;这个API则是用来获取某个地址对应的文件名和行号的，这两个函数的32位版本则是不带64的。有了这些Windows API，我们就可以很轻松的获取到当前函数的调用堆栈了，主要的功劳还是要归功于Windows强大的dbghelp。<br />
<br />
最后，完整的代码你可以在<a href="http://code.google.com/p/qlanguage/" target="_blank">http://code.google.com/p/qlanguage/</a>中找到。<img src ="http://www.cppblog.com/lwch/aggbug/197415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2013-01-19 20:09 <a href="http://www.cppblog.com/lwch/archive/2013/01/19/197415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何比较两个变量的类型是否相同</title><link>http://www.cppblog.com/lwch/archive/2012/08/25/188253.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 25 Aug 2012 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/08/25/188253.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/188253.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/08/25/188253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/188253.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/188253.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(T1,&nbsp;T2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">float</span>,&nbsp;<span style="color: #0000FF; ">float</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">double</span>,&nbsp;<span style="color: #0000FF; ">double</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">char</span>,&nbsp;<span style="color: #0000FF; ">char</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(wchar_t,&nbsp;wchar_t)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(T1*,&nbsp;T2*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;compare_type(T1(),&nbsp;T2());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">const</span>&nbsp;T1*,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T2*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;compare_type(T1(),&nbsp;T2());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(<span style="color: #0000FF; ">const</span>&nbsp;T1*,&nbsp;T2*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;compare_type(T1*,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T2*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
通过特例化，我们可以很轻松的查看两个变量的类型是否相同。<img src ="http://www.cppblog.com/lwch/aggbug/188253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-08-25 16:13 <a href="http://www.cppblog.com/lwch/archive/2012/08/25/188253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之list</title><link>http://www.cppblog.com/lwch/archive/2012/08/09/186770.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Thu, 09 Aug 2012 13:17:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/08/09/186770.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/186770.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/08/09/186770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/186770.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/186770.html</trackback:ping><description><![CDATA[在STL中list是以双向链表的方式来存储的，应此使用给定的下标值来找到对应的节点所需的时间复杂度为O(n)，相比vector直接使用原生指针会慢一些。<br />
<br />
因为是双向链表的关系，那么必然有一种结构来表示链表中的节点。<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;__list_node<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_node&lt;T&gt;*&nbsp;prev;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_node&lt;T&gt;*&nbsp;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;data;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_node()&nbsp;:&nbsp;prev(NULL),&nbsp;next(NULL)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_node(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)&nbsp;:&nbsp;prev(NULL),&nbsp;next(NULL),&nbsp;data(x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
<br />
然后我们定义出其iterator和const_iterator的结构<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;__list_iterator<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__list_iterator&lt;T&gt;&nbsp;iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ptrdiff_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__list_node&lt;T&gt;*&nbsp;&nbsp;&nbsp;&nbsp;link_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void_pointer;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link_type&nbsp;node;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_iterator(link_type&nbsp;x)&nbsp;:&nbsp;node(x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_iterator(<span style="color: #0000FF; ">const</span>&nbsp;__list_const_iterator&lt;T&gt;&amp;&nbsp;x)&nbsp;:&nbsp;node(x.node)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__list_iterator()&nbsp;:&nbsp;node(NULL)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&amp;&nbsp;<span style="color: #0000FF; ">operator</span>++()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;=&nbsp;((link_type)node)-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&nbsp;<span style="color: #0000FF; ">operator</span>++(<span style="color: #0000FF; ">int</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;tmp&nbsp;=&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&amp;&nbsp;<span style="color: #0000FF; ">operator</span>--()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;=&nbsp;((link_type)node)-&gt;prev;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&nbsp;<span style="color: #0000FF; ">operator</span>--(<span style="color: #0000FF; ">int</span>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;tmp&nbsp;=&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;reference&nbsp;<span style="color: #0000FF; ">operator</span>*()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node-&gt;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>==(<span style="color: #0000FF; ">const</span>&nbsp;iterator&amp;&nbsp;x)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node&nbsp;==&nbsp;x.node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;<span style="color: #0000FF; ">operator</span>!=(<span style="color: #0000FF; ">const</span>&nbsp;iterator&amp;&nbsp;x)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node&nbsp;!=&nbsp;x.node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
由于const_iterator与iterator的结构类似，这里不再贴出。其中重载了++与--运算符，实际上就是节点的前后移动。<br />
<br />
然后看一下list的定义<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;list<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
让我们来看看list中的别名<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__list_iterator&lt;T&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__list_const_iterator&lt;T&gt;&nbsp;const_iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;size_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ptrdiff_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;reverse_iterator&lt;const_iterator,&nbsp;value_type,&nbsp;size_type,&nbsp;difference_type&gt;&nbsp;const_reverse_iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;reverse_iterator&lt;iterator,&nbsp;value_type,&nbsp;size_type,&nbsp;difference_type&gt;&nbsp;reverse_iterator;</div>
<br />
下面是其内部的成员变量<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">protected</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__list_node&lt;T&gt;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;list&lt;T&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;allocator&lt;__list_node&lt;T&gt;&nbsp;&gt;&nbsp;Node_Alloc;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link_type&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_type&nbsp;length;</div>
在STL中从begin到end总是以一个前闭后开的形式来表示的，应此我们给出一个node节点来表示end所指位置，而node节点的前驱则是这个list的起始节点，而length则存储了这个list的元素数量。<br />
<br />
下面来看看list中最基本的构造函数和析构函数<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list()&nbsp;:&nbsp;length(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;=&nbsp;Node_Alloc::allocate();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node-&gt;next&nbsp;=&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node-&gt;prev&nbsp;=&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~list()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clear();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node_Alloc::deallocate(node);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
在list对象构造之初，首先构造出node节点，使其的前驱和后继都指向其本身，应此通过begin和end拿出的迭代器为同一个。在list对象析构时，首先将这个list清空，然后将构造出的node节点释放掉。<br />
<br />
然后是其begin和end方法，用来获取第一个元素和最后一个元素的后一个元素的迭代器<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;iterator&nbsp;begin()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_iterator&nbsp;begin()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&nbsp;end()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_iterator&nbsp;end()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
front和back分别被用来获取第一个元素和最后一个元素<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;reference&nbsp;front()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_reference&nbsp;front()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;reference&nbsp;back()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_reference&nbsp;back()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
empty、size分别被用来判别容器是否为空、获取容器内元素的个数<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;empty()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;length&nbsp;==&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;size_type&nbsp;size()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;length;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
list与vector不同的是list是双向的，应此它允许从头尾两个方向来插入和删除元素<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;push_front(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(begin(),&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;push_back(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert(end(),&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;pop_front()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erase(begin());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;pop_back()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;erase(--end());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
然后我们来看一下push的本质，insert函数<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iterator&nbsp;insert(<span style="color: #0000FF; ">const</span>&nbsp;iterator&amp;&nbsp;position,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(!inRange(position))&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;"out&nbsp;of&nbsp;range";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link_type&nbsp;tmp&nbsp;=&nbsp;Node_Alloc::allocate();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;construct(tmp,&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp-&gt;prev&nbsp;=&nbsp;position.node-&gt;prev;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp-&gt;next&nbsp;=&nbsp;position.node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.node-&gt;prev-&gt;next&nbsp;=&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.node-&gt;prev&nbsp;=&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++length;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
这里首先会检查这个迭代器是否属于这个list，然后构造出一个新节点，并把它插入到这个迭代器的前面，最后将节点数+1。<br />
<br />
然后是其删除节点函数erase<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;erase(<span style="color: #0000FF; ">const</span>&nbsp;iterator&amp;&nbsp;position)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(!inRange(position))&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;"out&nbsp;of&nbsp;range";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.node-&gt;prev-&gt;next&nbsp;=&nbsp;position.node-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.node-&gt;next-&gt;prev&nbsp;=&nbsp;position.node-&gt;prev;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(&amp;position.node-&gt;data,&nbsp;has_destruct(position.node-&gt;data));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node_Alloc::deallocate(position.node);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--length;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
这里同样会检查这个迭代器是否属于这个list，然后将这个节点移除，最后析构并释放内存空间。<br />
<br />
最后让我们来看一下list中重载的运算符<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;self&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(<span style="color: #0000FF; ">this</span>&nbsp;==&nbsp;&amp;x)&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;first1&nbsp;=&nbsp;begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;last1&nbsp;=&nbsp;end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_iterator&nbsp;first2&nbsp;=&nbsp;x.begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_iterator&nbsp;last2&nbsp;=&nbsp;x.end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(first1&nbsp;!=&nbsp;last1&nbsp;&amp;&amp;&nbsp;first2&nbsp;!=&nbsp;last2)&nbsp;*first1++&nbsp;=&nbsp;*first2++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(first2&nbsp;==&nbsp;last2)&nbsp;erase(first1,&nbsp;last1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;insert(last1,&nbsp;first2,&nbsp;last2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference&nbsp;<span style="color: #0000FF; ">operator</span>[](size_type&nbsp;n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;&lt;&nbsp;0&nbsp;||&nbsp;n&nbsp;&gt;=&nbsp;length)&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;"out&nbsp;of&nbsp;range";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;link_type&nbsp;current&nbsp;=&nbsp;NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;&lt;&nbsp;length&nbsp;/&nbsp;2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;node-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(size_type&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i++,&nbsp;current&nbsp;=&nbsp;current-&gt;next);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;=&nbsp;length&nbsp;-&nbsp;n&nbsp;-&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;node-&gt;prev;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(size_type&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i++,&nbsp;current&nbsp;=&nbsp;current-&gt;prev);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;current-&gt;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;value_type&nbsp;at(size_type&nbsp;n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">operator</span>[](n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
因为其内部使用的是双向链表，应此通过指定下标来获取这个元素是可分别从两头进行移动指针。<br />
<br />
至此，list的讲解已完成，完整代码请到<a href="http://qlanguage.codeplex.com/" target="_blank">http://qlanguage.codeplex.com</a>下载<img src ="http://www.cppblog.com/lwch/aggbug/186770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-08-09 21:17 <a href="http://www.cppblog.com/lwch/archive/2012/08/09/186770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之内存池</title><link>http://www.cppblog.com/lwch/archive/2012/07/14/183420.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 14 Jul 2012 10:40:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/07/14/183420.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/183420.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/07/14/183420.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/183420.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/183420.html</trackback:ping><description><![CDATA[内存池的作用：<br />
减少内存碎片，提高性能。<br />
<br />
首先不得不提的是Win32和x64中对于指针的长度是不同的，<strong>在Win32中一个指针占4字节，而在x64中一个指针占8字节</strong>。也正是不清楚这一点，当我在x64中将指针作为4字节修改造成其他数据异常。<br />
<br />
首先我们先来定义三个宏<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;ALIGN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sizeof(void*)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;MAX_BYTES&nbsp;128<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">#define</span>&nbsp;MAX_COUNT&nbsp;(MAX_BYTES&nbsp;/&nbsp;ALIGN)</div>
正如前面所说的，为了兼容Win32与x64应此我们将要申请的内存按void*的大小来对齐。正如前面所说的，我们认为小于128字节的内存为小内存，会产生内存碎片，应此在申请时应该劲量申请一块较大的内存而将其中的一小块分配给他。<br />
<br />
然后让我们来看一下内存池中的成员变量<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;obj<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;block<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>*&nbsp;&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;&nbsp;&nbsp;chunk_list[MAX_COUNT];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;chunk_count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;free_list;</div>
这里使用obj结构来存储已释放内存的列表，这样做的好处是可以更节省内存。在Win32中使用这块内存的前4字节来指向下一个节点，而在x64中使用这块内存的前8字节来指向下一个节点。<br />
chunk_list：保存通过deallocate或refill中释放或是新申请的内存块列表，deallocate和refill将会在下文中介绍。<br />
chunk_count：内存块列表中已有的内存块数量。<br />
free_list：保存了通过malloc申请内存块的链表。<br />
<br />
下面我们来看一下内存池的构造函数与析构函数<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MemoryPool()&nbsp;:&nbsp;free_list(0),&nbsp;chunk_count(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;MAX_COUNT;&nbsp;++i)&nbsp;chunk_list[i]&nbsp;=&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~MemoryPool()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;current&nbsp;=&nbsp;free_list;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(current)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;next&nbsp;=&nbsp;current-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(current-&gt;data);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(current);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
构造函数中初始化free_list和chunk_count为0，并初始化chunk_list为一个空列表。而在析构函数中我们必须释放每一块通过malloc申请的大内存块。<br />
<br />
接下来是内存的申请<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T*&nbsp;allocate(size_t&nbsp;n,&nbsp;<span style="color: #0000FF; ">void</span>(*h)(size_t))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;==&nbsp;0)&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;&gt;&nbsp;MAX_BYTES)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T*&nbsp;p&nbsp;=&nbsp;(T*)malloc(n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(p&nbsp;==&nbsp;0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h(n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;(T*)malloc(n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;p;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;INDEX(ROUND_UP(n));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;p&nbsp;=&nbsp;chunk_list[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(p&nbsp;==&nbsp;0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;refill&lt;T&gt;(i,&nbsp;h);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;p-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;reinterpret_cast&lt;T*&gt;(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
值得注意的是，在调用时必须传入一个函数指针作为参数，当malloc申请内存失败时会去调用这个函数来释放出足够多的内存空间。当要申请的内存大小超过128字节时，调用默认的malloc为其申请内存。否则先查找列表中是否还有足够的空间分配给它，若已没有足够的空间分配给它，则调用refill申请一块大内存。<br />
<br />
然后是内存释放函数deallocate<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;deallocate(T*&nbsp;p,&nbsp;size_t&nbsp;n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(p&nbsp;==&nbsp;0)&nbsp;<span style="color: #0000FF; ">return</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;&gt;&nbsp;MAX_BYTES)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;INDEX(ROUND_UP(n));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reinterpret_cast&lt;obj*&gt;(p)-&gt;next&nbsp;=&nbsp;chunk_list[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;reinterpret_cast&lt;obj*&gt;(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
值得注意的是在释放时必须给出这块内存块的大小。若这块内存大于128字节时，调用默认的free函数释放掉这块内存。否则将其加到对应的chunk_list列表内。<br />
<br />
然后是调整内存块大小函数reallocate<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T*&nbsp;reallocate(T*&nbsp;p,&nbsp;size_t&nbsp;old_size,&nbsp;size_t&nbsp;new_size,&nbsp;<span style="color: #0000FF; ">void</span>(*h)(size_t))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(old_size&nbsp;&gt;&nbsp;MAX_BYTES&nbsp;&amp;&amp;&nbsp;new_size&nbsp;&gt;&nbsp;MAX_BYTES)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;realloc(p,&nbsp;new_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(ROUND_UP(old_size)&nbsp;==&nbsp;ROUND_UP(new_size))&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;p;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T*&nbsp;result&nbsp;=&nbsp;allocate&lt;T&gt;(new_size,&nbsp;h);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_t&nbsp;copy_size&nbsp;=&nbsp;new_size&nbsp;&gt;&nbsp;old_size&nbsp;?&nbsp;old_size&nbsp;:&nbsp;new_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(result,&nbsp;p,&nbsp;copy_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deallocate&lt;T&gt;(p,&nbsp;old_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
参数中必须给出这块内存的原始大小和要调整后的大小，同时也必须给出当内存不足时的释放函数的指针。若旧内存块和新内存块的大小都大于128字节时，调用默认的realloc函数重新分配内存。否则先按调整后的大小申请一块内存，并把原来的内容拷贝过来，最后释放掉原来的内存块。这里并不建议使用这个函数，而是手动的去重新申请内存并拷贝释放。<br />
<br />
然后来看4个非常简单的计算函数<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;size_t&nbsp;ROUND_UP(size_t&nbsp;bytes)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(bytes&nbsp;+&nbsp;ALIGN&nbsp;-&nbsp;1)&nbsp;&amp;&nbsp;~(ALIGN&nbsp;-&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;size_t&nbsp;ROUND_DOWN(size_t&nbsp;bytes)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;bytes&nbsp;&amp;&nbsp;~(ALIGN&nbsp;-&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;INDEX(size_t&nbsp;bytes)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(bytes&nbsp;+&nbsp;ALIGN&nbsp;-&nbsp;1)&nbsp;/&nbsp;ALIGN&nbsp;-&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;size_t&nbsp;obj_count(<span style="color: #0000FF; ">int</span>&nbsp;i)<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;result&nbsp;=&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;current&nbsp;=&nbsp;chunk_list[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(current)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;current-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
前3个用于内存对齐和计算索引，最后一个用于获取一在空闲列表内一个内存块的数量。<br />
<br />
然后是refill函数，用于在没有空闲内存块时申请一块大内存块<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T*&nbsp;refill(<span style="color: #0000FF; ">int</span>&nbsp;i,&nbsp;<span style="color: #0000FF; ">void</span>(*h)(size_t))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;count&nbsp;=&nbsp;20;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;preSize&nbsp;=&nbsp;(i&nbsp;+&nbsp;1)&nbsp;*&nbsp;ALIGN;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>*&nbsp;p&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(preSize&nbsp;*&nbsp;count);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(p&nbsp;==&nbsp;0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h(preSize&nbsp;*&nbsp;count);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;=&nbsp;(<span style="color: #0000FF; ">char</span>*)malloc(preSize&nbsp;*&nbsp;count);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block*&nbsp;pBlock&nbsp;=&nbsp;(block*)malloc(<span style="color: #0000FF; ">sizeof</span>(block));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(pBlock&nbsp;==&nbsp;0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h(<span style="color: #0000FF; ">sizeof</span>(block));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock&nbsp;=&nbsp;(block*)malloc(<span style="color: #0000FF; ">sizeof</span>(block));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock-&gt;data&nbsp;=&nbsp;p;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pBlock-&gt;next&nbsp;=&nbsp;free_list;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free_list&nbsp;=&nbsp;pBlock;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;current&nbsp;=&nbsp;(obj*)(p&nbsp;+&nbsp;preSize);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;count&nbsp;-&nbsp;1;&nbsp;++j)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current-&gt;next&nbsp;=&nbsp;chunk_list[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;current;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;(obj*)((<span style="color: #0000FF; ">char</span>*)current&nbsp;+&nbsp;preSize);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_count&nbsp;+=&nbsp;count&nbsp;-&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rebalance();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;reinterpret_cast&lt;T*&gt;(p);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
首先申请一个大内存块，然后将这块申请到的内存块放入free_list链表内，最后组织起chunk_list中对应内存卡块的链表，然后重新调整chunk_list列表，最后将申请到的内存块返回。<br />
<br />
最后来看一下调整函数rebalance<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;rebalance()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;MAX_COUNT&nbsp;-&nbsp;1;&nbsp;i&nbsp;&gt;&nbsp;0;&nbsp;--i)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_t&nbsp;avge&nbsp;=&nbsp;chunk_count&nbsp;/&nbsp;MAX_COUNT;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;count&nbsp;=&nbsp;obj_count(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(count&nbsp;&gt;&nbsp;avge)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;preSize&nbsp;=&nbsp;ROUND_DOWN((i&nbsp;+&nbsp;1)&nbsp;*&nbsp;ALIGN&nbsp;/&nbsp;2);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;INDEX(preSize);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;k&nbsp;=&nbsp;count;&nbsp;k&nbsp;&gt;&nbsp;avge;&nbsp;--k)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;chunk&nbsp;=&nbsp;chunk_list[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[i]&nbsp;=&nbsp;chunk_list[i]-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(i&nbsp;%&nbsp;2&nbsp;==&nbsp;1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk-&gt;next&nbsp;=&nbsp;(obj*)((<span style="color: #0000FF; ">char</span>*)chunk&nbsp;+&nbsp;preSize);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk-&gt;next-&gt;next&nbsp;=&nbsp;chunk_list[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[j]&nbsp;=&nbsp;chunk;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk-&gt;next&nbsp;=&nbsp;chunk_list[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[j]&nbsp;=&nbsp;chunk;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj*&nbsp;next&nbsp;=&nbsp;(obj*)((<span style="color: #0000FF; ">char</span>*)chunk&nbsp;+&nbsp;preSize);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next-&gt;next&nbsp;=&nbsp;chunk_list[j&nbsp;+&nbsp;1];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chunk_list[j&nbsp;+&nbsp;1]&nbsp;=&nbsp;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++chunk_count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
这里从后至前查看对应内存块空闲链表的长度，若超过平均数量，则将其切分为2块较小的内存块放入对应的链表内。这样做的好处是可以形成一个金字塔形的分布状况，既越小的内存块大小拥有的节点数量越多，正如本文开头所说，使用内存池是为了解决在申请小块内存时造成的内存碎片。<br />
<br />
至此，内存池的讲解已完成，完整的代码请到<a href="http://qlanguage.codeplex.com/" target="_blank">http://qlanguage.codeplex.com</a>下载<img src ="http://www.cppblog.com/lwch/aggbug/183420.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-07-14 18:40 <a href="http://www.cppblog.com/lwch/archive/2012/07/14/183420.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之vector</title><link>http://www.cppblog.com/lwch/archive/2012/06/17/179179.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 17 Jun 2012 09:08:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/06/17/179179.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/179179.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/06/17/179179.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/179179.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/179179.html</trackback:ping><description><![CDATA[首先是vector的定义<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;vector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
<br />
让我们先来看看vector中的一些别名<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">public</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;size_t&nbsp;&nbsp;&nbsp;&nbsp;size_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ptrdiff_t&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;const_iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;reverse_iterator&lt;const_iterator,&nbsp;value_type,&nbsp;size_type,&nbsp;difference_type&gt;&nbsp;const_reverse_iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;iterator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;reverse_iterator&lt;iterator,&nbsp;value_type,&nbsp;size_type,&nbsp;difference_type&gt;&nbsp;reverse_iterator;</div>
由上可见，正如<a href="http://www.cppblog.com/lwch/archive/2012/06/02/177248.html">上一篇</a>所说，vector的迭代器是由原生的指针来实现的。<br />
<br />
下面是其内部的成员变量<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">protected</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;vector&lt;T&gt;&nbsp;&nbsp;&nbsp;&nbsp;self;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;allocator&lt;T&gt;&nbsp;Alloc;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;start;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;end_of_element;</div>
start：指向vector的起始地址<br />
finish：指向最后一个元素的后一个元素的地址<br />
end_of_element：指向已申请内存块的结束位置（finish总是小于或等于end_of_element）<br />
<br />
在STL中从begin到end总是以一个前闭后开的形式来表示的，形如[begin,end)，这样做的好处是可以使代码写的更简洁：<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;Iterator,&nbsp;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterator&nbsp;find(Iterator&nbsp;first,&nbsp;Iterator&nbsp;last,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;value)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(first&nbsp;!=&nbsp;last&nbsp;&amp;&amp;&nbsp;*first&nbsp;!=&nbsp;value)&nbsp;++first;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;first;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
下面来看看vector中最基本的构造函数和析构函数<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vector()&nbsp;:&nbsp;start(0),&nbsp;finish(0),&nbsp;end_of_element(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~vector()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(start,&nbsp;end_of_element);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(start&nbsp;!=&nbsp;0)&nbsp;Alloc::deallocate(start,&nbsp;end_of_element&nbsp;-&nbsp;start);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
这里将其中的3个成员变量都填充为0。<br />
如<a href="http://www.cppblog.com/lwch/archive/2012/06/02/177248.html">上一篇</a>所说，在STL中是将内存分配与对象初始化分开的，同样对象析构与内存释放也是被分开的。<br />
<br />
然后是其begin和end方法，用来获取第一个元素和最后一个元素的后一个元素的迭代器。<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;iterator&nbsp;begin()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;start;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_iterator&nbsp;begin()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;start;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;iterator&nbsp;end()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_iterator&nbsp;end()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
front和back分别被用来获取第一个元素和最后一个元素<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;reference&nbsp;front()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_reference&nbsp;front()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;reference&nbsp;back()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*(end()&nbsp;-&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;const_reference&nbsp;back()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*(end()&nbsp;-&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
empty、size、capacity分别被用来判别容器是否为空、容器内元素的个数和容器的大小<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;<span style="color: #0000FF; ">bool</span>&nbsp;empty()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;begin()&nbsp;==&nbsp;end();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_type&nbsp;size()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;size_type(end()&nbsp;-&nbsp;begin());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_type&nbsp;capacity()<span style="color: #0000FF; ">const</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;size_type(end_of_element&nbsp;-&nbsp;begin());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
<br />
由于在vector的头部插入元素会使所有元素后移，应此它被设计为单向的，只能由尾部插入或移除数据<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;push_back(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(end_of_element&nbsp;!=&nbsp;finish)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;construct(&amp;*finish,&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert_aux(end(),&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;pop_back()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct&lt;T&gt;(finish,&nbsp;has_destruct(*finish));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
当然从头部移除数据也并非不可以，可以使用erase方法来移除头部的数据，erase方法将会在后面的部分作出说明。<br />
<br />
我们先来看一下insert_aux这个方法，在插入元素时几乎都使用到了这个方法。<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;insert_aux(<span style="color: #0000FF; ">const</span>&nbsp;iterator&nbsp;position,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(finish&nbsp;!=&nbsp;end_of_element)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;construct(&amp;*finish,&nbsp;*(finish&nbsp;-&nbsp;1));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;x_copy&nbsp;=&nbsp;x;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy_backward(position,&nbsp;finish&nbsp;-&nbsp;1,&nbsp;finish);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*position&nbsp;=&nbsp;x_copy;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_type&nbsp;old_size&nbsp;=&nbsp;size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_type&nbsp;new_size&nbsp;=&nbsp;old_size&nbsp;==&nbsp;0&nbsp;?&nbsp;2&nbsp;:&nbsp;old_size&nbsp;*&nbsp;2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;tmp&nbsp;=&nbsp;Alloc::allocate(new_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uninitialized_copy(begin(),&nbsp;position,&nbsp;tmp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;new_position&nbsp;=&nbsp;tmp&nbsp;+&nbsp;(position&nbsp;-&nbsp;begin());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;construct(&amp;*new_position,&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uninitialized_copy(position,&nbsp;end(),&nbsp;new_position&nbsp;+&nbsp;1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(begin(),&nbsp;end());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Alloc::deallocate(begin(),&nbsp;old_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end_of_element&nbsp;=&nbsp;tmp&nbsp;+&nbsp;new_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finish&nbsp;=&nbsp;tmp&nbsp;+&nbsp;old_size&nbsp;+&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;=&nbsp;tmp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
在容器还有足够的空间时，首先将从position位置到finish位置的元素整体后移一个位置，最后将要被插入的元素写入到原position的位置同时改变finish指针的值。<br />
若空间不足时，首先根据原有空间的大小的一倍来申请内存，然后将元素从原有位置的begin到position拷贝到新申请的内存中，然后在新申请内存的指定位置插入要插入的元素值，最后将余下的部分也拷贝过来。然后将原有元素析构掉并把内存释放掉。<br />
<br />
<span style="color: red; ">为何不使用</span><span style="color: red; ">reallocate?</span><br />
reallocate的本意并不是在原有内存的位置增加或减少内存，reallocate首先会试图在原有的内存位置增加或减少内存，<strong>若失败则会重新申请一块新的内存并把原有的数据拷贝过去</strong>，这种操作本质上等价于重新申请一块内存，应此这里使用的是allocate而并非reallocate。<br />
<br />
然后让我们来看一下insert和erase方法<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inline&nbsp;iterator&nbsp;insert(iterator&nbsp;position,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;size_type&nbsp;pos&nbsp;=&nbsp;position&nbsp;-&nbsp;begin();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(finish&nbsp;!=&nbsp;end_of_element&nbsp;&amp;&amp;&nbsp;position&nbsp;==&nbsp;end())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;construct(&amp;*finish,&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;insert_aux(position,&nbsp;x);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;begin()&nbsp;+&nbsp;pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator&nbsp;erase(iterator&nbsp;position)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(position,&nbsp;has_destruct(*position));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(position&nbsp;+&nbsp;1&nbsp;!=&nbsp;end())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy(position&nbsp;+&nbsp;1,&nbsp;end(),&nbsp;position);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--finish;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;position;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
若是要在最后插入一个元素且容器的剩余空间还足够的话，直接将元素插入到finish的位置，并将finish指针后移一位即可。若容器空间不够或不是插在最后一个的位置，则调用insert_aux重新分配内存或插入。<br />
删除时首先析构掉原有元素，若被删元素不是最后一个元素，则将后面的所有元素拷贝过来，最后将finish指针前移一个位置。<br />
<br />
最后让我们来看一下其中重载的运算符<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self&amp;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;self&amp;&nbsp;x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(&amp;x&nbsp;==&nbsp;<span style="color: #0000FF; ">this</span>)&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_type&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;other_size&nbsp;=&nbsp;x.size();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(other_size&nbsp;&gt;&nbsp;capacity())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(start,&nbsp;finish);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Alloc::deallocate(start,&nbsp;capacity());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;=&nbsp;Alloc::allocate(other_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finish&nbsp;=&nbsp;uninitialized_copy(x.begin(),&nbsp;x.end(),&nbsp;start);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end_of_element&nbsp;=&nbsp;start&nbsp;+&nbsp;other_size;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finish&nbsp;=&nbsp;uninitialized_copy(x.begin(),&nbsp;x.end(),&nbsp;start);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;reference&nbsp;<span style="color: #0000FF; ">operator</span>[](size_type&nbsp;n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*(begin()&nbsp;+&nbsp;n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;value_type&nbsp;at(size_type&nbsp;n)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*(begin()&nbsp;+&nbsp;n);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
由于vector内部用的是原生的指针，应此这些运算符的使用方式和原生指针的并无差异。<strong>值得注意的是在做赋值操作时会产生内存的重新分配与拷贝操作。<br />
</strong><br />
至此，vector的讲解已完成，完整的代码请到<a href="http://qlanguage.codeplex.com" target="_blank">http://qlanguage.codeplex.com</a>下载<img src ="http://www.cppblog.com/lwch/aggbug/179179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-06-17 17:08 <a href="http://www.cppblog.com/lwch/archive/2012/06/17/179179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之traits,construct&amp;destruct</title><link>http://www.cppblog.com/lwch/archive/2012/06/02/177248.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sat, 02 Jun 2012 14:39:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/06/02/177248.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/177248.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/06/02/177248.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/177248.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/177248.html</trackback:ping><description><![CDATA[traits技术被广泛应用于STL中，通过它您可以轻松的萃取出一个对象的特性。在STL中也是通过它来实现性能的最优化，比如一个对象是个POD对象(Plain Old Data)，则在拷贝过程中直接可以通过memcpy等函数拷贝，而无需调用拷贝构造函数或operator=。<br />
<br />
先来看看STL中最基本的对象iterator<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T,&nbsp;typename&nbsp;Size&nbsp;=&nbsp;size_t,&nbsp;typename&nbsp;Difference&nbsp;=&nbsp;ptrdiff_t&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;iterator<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Difference&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;iterator&lt;T,&nbsp;Size,&nbsp;Difference&gt;&nbsp;&nbsp;&nbsp;self;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T,&nbsp;typename&nbsp;Size&nbsp;=&nbsp;size_t,&nbsp;typename&nbsp;Difference&nbsp;=&nbsp;ptrdiff_t&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;const_iterator&nbsp;:&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;iterator&lt;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
由以上代码可知，对于每一个iterator必须定义其value_type,size_type,difference_type,pointer,reference,const_pointer,const_reference和self类型。&nbsp;<br /><strong>一、value_type</strong><br />
value_type指示了该迭代器所保存的值类型<br />
<strong>二、difference_type</strong><br />
difference_type用来指示两个迭代器之间的距离类型<br />
<strong>三、pointer,reference,const_pointer,const_reference</strong><br />
分别是所指之物的指针,引用,指针常量和引用常量的类型<br />
<strong>四、self</strong><br />
self为该迭代器自身的类型<br />
<br />
下面来看一下iterator_traits，iterator_traits主要用来萃取迭代器iterator的值类型等<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;Iterator&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;iterator_traits<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::value_type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::difference_type&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::pointer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::reference&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::const_pointer&nbsp;&nbsp;&nbsp;const_pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::const_reference&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Iterator::self&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
<br />
这里有一点可以提前预告一下，vector作为一个容器，其内部是使用指针作为迭代器的，那么我们如何萃取出它的值类型等呢？<br />
答案很简单，特例化，那么我们就来为iterator_traits分别做两种T*和const T*的特例化<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;iterator_traits&lt;T*&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ptrdiff_t&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;&nbsp;const_pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;iterator_traits&lt;<span style="color: #0000FF; ">const</span>&nbsp;T*&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ptrdiff_t&nbsp;difference_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;&nbsp;const_pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;&nbsp;const_reference;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T*&nbsp;&nbsp;self_type;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
至此，我们可以用iterator_traits萃取出每种iterator的值类型等内容了。<br />
<br />
之前已经说到了，通过traits可以萃取出一些对象的特性，从而提高代码的效率。事实确实如此，通过traits可萃取出一个对象是否是一个POD对象，对于一个POD对象，我们在拷贝时，不应该使用其拷贝构造函数或是operator=，而用memcpy则效率更高。<br />
下面我们来看一下__type_traits<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;__true_type<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;__false_type<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;I&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">struct</span>&nbsp;__type_traits<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__false_type&nbsp;has_default_construct;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__false_type&nbsp;has_copy_construct;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__false_type&nbsp;has_assign_operator;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__false_type&nbsp;has_destruct;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;__false_type&nbsp;is_POD;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</div>
不得不提的是其中分别用__true_type和__false_type来表示是否存在这个特性。<br />
<br />
那么我们如何萃取出基础类型诸如int,char等的特性呢？<br />
答案依然是特例化，这里代码不再贴出，文末会给出完整代码的详细地址。<br />
<br />
最后我们使用一个hash_destruct的函数来获取出这个类型是否有析构函数。<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;auto&nbsp;has_destruct(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;)-&gt;decltype(static_cast&lt;__type_traits&lt;T&gt;::has_destruct*&gt;(0))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;static_cast&lt;typename&nbsp;__type_traits&lt;T&gt;::has_destruct*&gt;(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;auto&nbsp;has_destruct(T*)-&gt;decltype(static_cast&lt;__type_traits&lt;T&gt;::has_destruct*&gt;(0))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static_assert(<span style="color: #0000FF; ">false</span>,&nbsp;"Please&nbsp;use&nbsp;const&nbsp;T&amp;&nbsp;not&nbsp;T*");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;static_cast&lt;typename&nbsp;__type_traits&lt;T&gt;::has_destruct*&gt;(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;auto&nbsp;has_destruct(<span style="color: #0000FF; ">const</span>&nbsp;T*)-&gt;decltype(static_cast&lt;__type_traits&lt;T&gt;::has_destruct*&gt;(0))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static_assert(<span style="color: #0000FF; ">false</span>,&nbsp;"Please&nbsp;use&nbsp;const&nbsp;T&amp;&nbsp;not&nbsp;const&nbsp;T*");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;static_cast&lt;typename&nbsp;__type_traits&lt;T&gt;::has_destruct*&gt;(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
不得不提的是C++0x的确很强大，可以通过形参来确定返回值的类型，这样我们就可以萃取出这个类型的has_destruct域是__true_type或是__false_type了。<br /><br />
最后来看看construct和destruct的代码，在STL中对象的内存分配和构造是被分开的，对于基础对象int,char等，在析构时我们无需调用其析构函数。<br />
下面来看construct和destruct的实现<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp; &nbsp; &nbsp; &nbsp; template&nbsp;&lt;typename&nbsp;T1,&nbsp;typename&nbsp;T2&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;construct(T1*&nbsp;p,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;T2&amp;&nbsp;value)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;(p)&nbsp;T1(value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;destruct(T*&nbsp;p,&nbsp;__true_type*)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p-&gt;~T();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;T&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;destruct(T*,&nbsp;__false_type*)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;&lt;typename&nbsp;ForwardIterator&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inline&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;destruct(ForwardIterator&nbsp;first,&nbsp;ForwardIterator&nbsp;last)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(first&nbsp;!=&nbsp;last)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;destruct(first,&nbsp;has_destruct(*first));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++first;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div>
至此，关于traits技术和construct及destruct的讲解已完成，完整的代码请到<a href="http://qlanguage.codeplex.com/" target="_blank">http://qlanguage.codeplex.com/</a>下载<img src ="http://www.cppblog.com/lwch/aggbug/177248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-06-02 22:39 <a href="http://www.cppblog.com/lwch/archive/2012/06/02/177248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现之allocator</title><link>http://www.cppblog.com/lwch/archive/2012/05/20/175498.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 20 May 2012 13:45:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/05/20/175498.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/175498.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/05/20/175498.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/175498.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/175498.html</trackback:ping><description><![CDATA[<div>作为一个山寨的STL，那么不得不提的是其中的allocator（空间配置器）。顾名思义，它是负责空间分配用的，下面代码十分简单，仅对C函数malloc和free进行了薄薄的一层封装，同时给定了自定义函数free_handler用于在空间分配时候由于内存被占满了而导致的分配失败。<br />
<br />
这里值得注意的是：这个释放函数的函数指针应该是由调用方来负责指定，并且它仅有一个参数表明至少需要释放多少字节的内存。<br />
<br />
下面来看代码，代码非常简单，应此这里就不逐一展开说明了。
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /><span style="color: #000000">#ifndef&nbsp;_QLANGUAGE_LIBRARY_ALLOC_H_<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;_QLANGUAGE_LIBRARY_ALLOC_H_</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#if</span><span style="color: #000000">&nbsp;0</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">new</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;__THROW_BAD_ALLOC&nbsp;throw&nbsp;std::bad_alloc</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#elif</span><span style="color: #000000">&nbsp;!defined(__THROW_BAD_ALLOC)</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#define</span><span style="color: #000000">&nbsp;__THROW_BAD_ALLOC&nbsp;std::cerr&nbsp;&lt;&lt;&nbsp;"out&nbsp;of&nbsp;memory"&nbsp;&lt;&lt;&nbsp;std::endl;&nbsp;exit(1)</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;QLanguage<br />
<img id="Codehighlighter1_300_2463_Open_Image" onclick="this.style.display='none'; Codehighlighter1_300_2463_Open_Text.style.display='none'; Codehighlighter1_300_2463_Closed_Image.style.display='inline'; Codehighlighter1_300_2463_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img style="display: none" id="Codehighlighter1_300_2463_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_300_2463_Closed_Text.style.display='none'; Codehighlighter1_300_2463_Open_Image.style.display='inline'; Codehighlighter1_300_2463_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_300_2463_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_300_2463_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;Library<br />
<img id="Codehighlighter1_328_2461_Open_Image" onclick="this.style.display='none'; Codehighlighter1_328_2461_Open_Text.style.display='none'; Codehighlighter1_328_2461_Closed_Image.style.display='inline'; Codehighlighter1_328_2461_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_328_2461_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_328_2461_Closed_Text.style.display='none'; Codehighlighter1_328_2461_Open_Image.style.display='inline'; Codehighlighter1_328_2461_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_328_2461_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_328_2461_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;allocator<br />
<img id="Codehighlighter1_392_2345_Open_Image" onclick="this.style.display='none'; Codehighlighter1_392_2345_Open_Text.style.display='none'; Codehighlighter1_392_2345_Closed_Image.style.display='inline'; Codehighlighter1_392_2345_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_392_2345_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_392_2345_Closed_Text.style.display='none'; Codehighlighter1_392_2345_Open_Image.style.display='inline'; Codehighlighter1_392_2345_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_392_2345_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_392_2345_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allocator()<br />
<img id="Codehighlighter1_446_460_Open_Image" onclick="this.style.display='none'; Codehighlighter1_446_460_Open_Text.style.display='none'; Codehighlighter1_446_460_Closed_Image.style.display='inline'; Codehighlighter1_446_460_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_446_460_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_446_460_Closed_Text.style.display='none'; Codehighlighter1_446_460_Open_Image.style.display='inline'; Codehighlighter1_446_460_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_446_460_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_446_460_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allocator(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;allocator</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;&amp;</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_518_532_Open_Image" onclick="this.style.display='none'; Codehighlighter1_518_532_Open_Text.style.display='none'; Codehighlighter1_518_532_Closed_Image.style.display='inline'; Codehighlighter1_518_532_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_518_532_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_518_532_Closed_Text.style.display='none'; Codehighlighter1_518_532_Open_Image.style.display='inline'; Codehighlighter1_518_532_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_518_532_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_518_532_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;allocate()<br />
<img id="Codehighlighter1_580_943_Open_Image" onclick="this.style.display='none'; Codehighlighter1_580_943_Open_Text.style.display='none'; Codehighlighter1_580_943_Closed_Image.style.display='inline'; Codehighlighter1_580_943_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_580_943_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_580_943_Closed_Text.style.display='none'; Codehighlighter1_580_943_Open_Image.style.display='inline'; Codehighlighter1_580_943_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_580_943_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_580_943_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(T);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)malloc(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(result&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;nullptr)<br />
<img id="Codehighlighter1_732_898_Open_Image" onclick="this.style.display='none'; Codehighlighter1_732_898_Open_Text.style.display='none'; Codehighlighter1_732_898_Closed_Image.style.display='inline'; Codehighlighter1_732_898_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_732_898_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_732_898_Closed_Text.style.display='none'; Codehighlighter1_732_898_Open_Image.style.display='inline'; Codehighlighter1_732_898_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_732_898_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_732_898_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(free_handler)&nbsp;free_handler(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;__THROW_BAD_ALLOC;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)malloc(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;result;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;allocate(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;n)<br />
<img id="Codehighlighter1_1006_1430_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1006_1430_Open_Text.style.display='none'; Codehighlighter1_1006_1430_Closed_Image.style.display='inline'; Codehighlighter1_1006_1430_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1006_1430_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1006_1430_Closed_Text.style.display='none'; Codehighlighter1_1006_1430_Open_Image.style.display='inline'; Codehighlighter1_1006_1430_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1006_1430_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1006_1430_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;n&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(T);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(size&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">bad&nbsp;allocate&nbsp;size</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)malloc(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(result&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;nullptr)<br />
<img id="Codehighlighter1_1219_1385_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1219_1385_Open_Text.style.display='none'; Codehighlighter1_1219_1385_Closed_Image.style.display='inline'; Codehighlighter1_1219_1385_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1219_1385_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1219_1385_Closed_Text.style.display='none'; Codehighlighter1_1219_1385_Open_Image.style.display='inline'; Codehighlighter1_1219_1385_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1219_1385_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1219_1385_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(free_handler)&nbsp;free_handler(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;__THROW_BAD_ALLOC;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)malloc(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;result;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;deallocate(T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p)<br />
<img id="Codehighlighter1_1486_1525_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1486_1525_Open_Text.style.display='none'; Codehighlighter1_1486_1525_Closed_Image.style.display='inline'; Codehighlighter1_1486_1525_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1486_1525_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1486_1525_Closed_Text.style.display='none'; Codehighlighter1_1486_1525_Open_Image.style.display='inline'; Codehighlighter1_1486_1525_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1486_1525_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1486_1525_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;deallocate(T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p,&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_1596_1635_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1596_1635_Open_Text.style.display='none'; Codehighlighter1_1596_1635_Closed_Image.style.display='inline'; Codehighlighter1_1596_1635_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1596_1635_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1596_1635_Closed_Text.style.display='none'; Codehighlighter1_1596_1635_Open_Image.style.display='inline'; Codehighlighter1_1596_1635_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1596_1635_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1596_1635_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(p);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;reallocate(T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p,&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;n)<br />
<img id="Codehighlighter1_1706_2140_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1706_2140_Open_Text.style.display='none'; Codehighlighter1_1706_2140_Closed_Image.style.display='inline'; Codehighlighter1_1706_2140_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1706_2140_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1706_2140_Closed_Text.style.display='none'; Codehighlighter1_1706_2140_Open_Image.style.display='inline'; Codehighlighter1_1706_2140_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1706_2140_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1706_2140_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t&nbsp;size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;n&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(T);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(size&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">bad&nbsp;reallocate&nbsp;size</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)realloc(p,&nbsp;size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(result&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;nullptr)<br />
<img id="Codehighlighter1_1925_2095_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1925_2095_Open_Text.style.display='none'; Codehighlighter1_1925_2095_Closed_Image.style.display='inline'; Codehighlighter1_1925_2095_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_1925_2095_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1925_2095_Closed_Text.style.display='none'; Codehighlighter1_1925_2095_Open_Image.style.display='inline'; Codehighlighter1_1925_2095_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_1925_2095_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_1925_2095_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(free_handler)&nbsp;free_handler(size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;__THROW_BAD_ALLOC;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(T</span><span style="color: #000000">*</span><span style="color: #000000">)realloc(p,&nbsp;size);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;result;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">free_handler)(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">);<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;set_handler(</span><span style="color: #0000ff">void</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">h)(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">))<br />
<img id="Codehighlighter1_2287_2335_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2287_2335_Open_Text.style.display='none'; Codehighlighter1_2287_2335_Closed_Image.style.display='inline'; Codehighlighter1_2287_2335_Closed_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img style="display: none" id="Codehighlighter1_2287_2335_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_2287_2335_Closed_Text.style.display='none'; Codehighlighter1_2287_2335_Open_Image.style.display='inline'; Codehighlighter1_2287_2335_Open_Text.style.display='inline';" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_2287_2335_Closed_Text"><img src="http://www.cppblog.com/Images/dot.gif" alt="" /></span><span id="Codehighlighter1_2287_2335_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free_handler&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;h;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">allocator</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">&gt;</span><span style="color: #000000">::free_handler)(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;size_t</span><span style="color: #000000">&amp;</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;nullptr;<br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" alt="" />}</span></span><span style="color: #000000"><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /><br />
<img align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" alt="" /></span><span style="color: #0000ff">#endif</span></div>
<br />
完整代码请到<a href="http://qlanguage.codeplex.com/" target="_blank">http://qlanguage.codeplex.com/</a>下载</div><img src ="http://www.cppblog.com/lwch/aggbug/175498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-05-20 21:45 <a href="http://www.cppblog.com/lwch/archive/2012/05/20/175498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>山寨STL实现笔记</title><link>http://www.cppblog.com/lwch/archive/2012/05/20/175491.html</link><dc:creator>lwch</dc:creator><author>lwch</author><pubDate>Sun, 20 May 2012 12:08:00 GMT</pubDate><guid>http://www.cppblog.com/lwch/archive/2012/05/20/175491.html</guid><wfw:comment>http://www.cppblog.com/lwch/comments/175491.html</wfw:comment><comments>http://www.cppblog.com/lwch/archive/2012/05/20/175491.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lwch/comments/commentRss/175491.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lwch/services/trackbacks/175491.html</trackback:ping><description><![CDATA[<ul>
     <li>数据结构
     <ol>
         <li><a href="http://www.cppblog.com/lwch/archive/2012/05/20/175498.html" target="_blank">allocator</a></li>
         <li><a href="http://www.cppblog.com/lwch/archive/2012/07/14/183420.html" target="_blank">内存池</a></li>
         <li><a href="http://www.cppblog.com/lwch/archive/2013/01/19/197415.html" target="_blank">内存池V2</a></li>
         <li><a href="http://www.cppblog.com/lwch/archive/2012/06/02/177248.html" target="_blank">traits,construct&amp;destruct</a></li>
         <li><a href="http://www.cppblog.com/lwch/archive/2012/06/17/179179.html" target="_blank">vector</a></li>
         <li><a href="http://www.cppblog.com/lwch/archive/2012/08/09/186770.html" target="_blank">list</a></li>
         <li>rbtree</li>
         <li>map&amp;set</li>
         <li>hashtable</li>
         <li>hash_map&amp;hash_set </li>
     </ol>
     </li>
     <li>算法 </li>
</ul><img src ="http://www.cppblog.com/lwch/aggbug/175491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lwch/" target="_blank">lwch</a> 2012-05-20 20:08 <a href="http://www.cppblog.com/lwch/archive/2012/05/20/175491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>