空间配置器(二)
来源:互联网 发布:电脑无损音乐播放软件 编辑:程序博客网 时间: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
- 空间配置器(二)
- 【STL】空间配置器(二):二级空间配置器
- STL空间配置器(二)
- 【STL】空间配置器剖析(二)
- STL空间配置器(二)
- 【STL深入学习】SGI STL空间配置器详解(二)-第二级空间配置器
- SGI STL空间配置器详解(二)-第二级空间配置器
- 《STL源码剖析》—— 空间配置器(二)
- 《STL源码剖析》笔记(二)空间配置器
- STL笔记(二):空间配置
- 深度剖析空间配置器(二)一二级配置器
- STL笔记(4)——空间配置器Allocator(二)
- STL源码分析--空间配置器的底层实现 (二)
- STL源码:空间配置器(二)构造和析构construct()/destroy()
- 《STL源码剖析》学习笔记之二 空间配置器
- STL源码剖析 笔记之二 空间配置器
- 《STL源码剖析》读书笔记二--空间配置器
- 空间配置器(c++)
- 【一些网站的收集】包含机器学习深度学习大牛主页等
- ConcurrentHashMap的锁分段技术
- 关于日期的时间戳应用
- UVa 10129 欧拉路
- acm 刷题 第二题喷水装置(一)
- 空间配置器(二)
- python —— time模块
- 利用Byteman来统计Java中方法的耗时
- 子线程访问 主线程控件
- [codeforces585F/51nod1587]Digits of Number Pi
- 关于广搜优化的半吊子总结
- mogodb的使用及自制工具类
- 在子线程中利用主线程的Handler的post()方法
- C++ char* 的若干问题之二:char*作为形参能否影响实参的值