空间配置器(二)

2 篇文章 0 订阅
提前声明:这个文章本来应该命名为空间配置器(一)的,也就是说,这篇文章应该诞生于上篇文章 之前的,然而,由于本人的原因,造成这样的失误。

最近一直在读《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_MALLOC
template<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 once
template<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();
}



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值