空间配置器(二)

来源:互联网 发布:电脑无损音乐播放软件 编辑:程序博客网 时间:2024/05/21 08:04
提前声明:这个文章本来应该命名为空间配置器(一)的,也就是说,这篇文章应该诞生于上篇文章 之前的,然而,由于本人的原因,造成这样的失误。

最近一直在读《STL源码剖析》的第2章节,在讲述空间配置器的外部接口的时候,并不是特别清楚,反倒是把两级空间配置器的底层实现细节搞得比较清晰,所以,上一篇文章先于本篇文章。这两天,仔细阅读了接口这一部分,然后加上对自己空间配置器的使用,决定再来整理此文。
1.空间配置器的外部接口:
在上一篇文章中,我们知道,大于128字节的,就调用一级空间配置器,小于128字节的就调用二级空间配置器,

整个设计究竟只开放一级空间配置器还是同时开放二级空间配置器,取决于__USE_MALLOC是否被定义,如果定义了,就调用一级空间配置器,如果没有定义,就调用二级空间配置器(中间有可能去调到一级空间配置器)。SGI STL并未定义__USE_MALLOC。(引至《STL源码剖析》侯捷著)

所以,无论如何,中间都有可能去调到malloc()函数。
也就是说,默认调用二级空间配置器,如果大于128字节,才去调用一级空间配置器。
下边给出一级空间配置器和二级空间配置器的外部包装接口:(注明:截取至《STL源码剖析》侯捷著)

这样对两级空间配置器的外部接口也是比较清楚了。
我们需要在Alloc.h的文件中补充外部接口:
#ifdef __USE_MALLOC    typedef __MallocAllocTemplate<0> Alloc;#else    typedef __DefaultAllocTemplate<false,0> Alloc;#endif//__USE_MALLOCtemplate<typename T,typename _Alloc = Alloc>class SimpleAlloc{public:    static T* Allocate(size_t n)    {       return (T*)(_Alloc::Allocate(n * sizeof(T)));    }    static T* Allocate()    {       return (T*)(_Alloc::Allocate(sizeof(T)));    }    static void Deallocate(T* ptr,size_t n)    {       _Alloc::Deallocate(ptr,n * sizeof(T));    }    static void Deallocate(T* ptr)    {       _Alloc::Deallocate(ptr,sizeof(T));    }};
2.空间配置器的使用
在上篇文章,我们使用trace跟踪来测试空间配置器的,这里,我们自己模拟实现一个容器list,然后使用自己的空间配置器。
//list.h文件#pragma once#include"Alloc.h"#include"Construct.h"template<typename T>struct ListNode{    T _data;    ListNode<T>* _prev;    ListNode<T>* _next;    ListNode(const T& x = T())       :_data(x)       ,_prev(NULL)       ,_next(NULL)    {}};template<typename T,typename Ref,typename Ptr>struct ListIterator{    typedef ListIterator<T,T&,T*> Self;    typedef ListNode<T> Node;    Node* _node;    ListIterator(Node* p)       :_node(p)    {}    Self& operator++()    {       _node = _node->_next;       return *this;    }    Self operator++(int)    {       Node* tmp = _node;       _node = _node->_next;       return tmp;    }    Self& operator--()    {       _node = _node->_prev;       return *this;    }    Self operator--(int)    {       Node* tmp = _node;       _node = _node->_prev;       return tmp;    }    Ref operator*()    {       return _node->_data;    }    Ptr operator->()    {       return &(operator*());    }    bool operator != (const Self& s) const    {       return _node != s._node;    }    bool operator == (const Self& s) const    {       return !(*this != s);    }};template<typename T,typename  _Alloc = Alloc>class List{    typedef ListNode<T> Node;    typedef SimpleAlloc<Node, _Alloc> ListNodeAllocator;public:    typedef ListIterator<T,T&,T*> Iterator;    typedef ListIterator<T,const T&,const T*> ConstIterator;    List()       :_head(NULL)    {       _head = BuyNode(T());       _head->_next = _head;       _head->_prev = _head;    }    ~List()    {       Clear();       DestroyNode(_head);    }    void Clear()    {       Iterator it = Begin();       while(it != End())       {           Node* del = it._node;           ++it;           DestroyNode(del);       }       _head->_prev = _head;       _head->_next = _head;    }    void Insert(Iterator pos,const T& x)    {       Node* cur = pos._node;       Node* prev = cur->_prev;       Node* tmp = BuyNode(x);       tmp->_next = cur;       prev->_next = tmp;       tmp->_prev = prev;       cur->_prev = tmp;    }    void Erase(Iterator pos)    {       Node* del = pos._node;       Node* prev = del->_prev;       Node* next = del->_next;       prev->_next = next;       next->_prev = prev;           }    Iterator Begin()    {       return _head->_next;    }    ConstIterator Begin() const    {       return _head->_next;    }    Iterator End()    {       return _head;    }    ConstIterator End() const    {       return _head;    }    void PushBack(const T& x)    {       Insert(Iterator(_head),x);    }protected:    Node* BuyNode(const T& x)    {       Node* node = ListNodeAllocator::Allocate();       Construct(node,x);       return node;    }    void DestroyNode(Node* ptr)    {       Destory(ptr);       ListNodeAllocator::Deallocate(ptr);    }private:    Node* _head;};//construct.h文件#pragma oncetemplate<class T1, class T2>inline void Construct(T1* p, T2 value){    new(p) T1(value);}template<class T>inline void Destory(T* p){    p->~T();}



2 0
原创粉丝点击