标签:
空间配置器隐藏在一切组件之后。
1.1 设计一个简单的空间配置器
根据STL的规范,以下是allocator的必要接口:
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind // 一个嵌套的(nested)class template。class rebind<U>拥有唯一成员other,是一个typedef,代表alloctor<U>
allocator::allocator() // default constructor
allocator::allocator(const allocator&) // copy constructor
template <class U>allocator::allocator(const allocator<U>&) //泛化的default constructor
allocator::~allocator() // default constructor
pointer allocator::address(reference x) const // 返回某个对象的地址。a.address(x)等同于&x
const_pointer allocator::address(const_reference x) const // 返回某个const对象的地址。a.address(x)等同于&x
pointer allocator::allocate(size_type n, const void* = 0) // 配置空间,足以存储n个T对象。第二个参数是个提示,可能会用来增进locality,可忽略
void allocator::deallocate(pointer p, size_type n) // 归还先前配置的空间
size_type allocator::max_size() const // 返回可成功配置的最大量
void allocator::construct(pointer p, const T& x) // 等同于new(const void*) p) T(x)
void allocator::destroy(pointer p) // 等同于p->~T()
1.2 一个简单的allocator源代码
1 // filename : qyalloc.h 2 #ifndef __QYALLOC__ 3 #define __QYALLOC__ 4 5 // placement new是operator new的一个重载版本,只是我们很少用到它。如果你想在已经分配的内存中创建一个对象,使用new是不行的。也就是说placement new允许你在一个已经分配好的内存中(栈或堆中)构造一个新的对象。原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。 6 // placement new的作用就是:创建对象(调用该类的构造函数)但是不分配内存,而是在已有的内存块上面创建对象。用于需要反复创建并删除的对象上,可以降低分配释放内存的性能消耗。请查阅placement new相关资料。 7 #include <new> // placement new 要包含此文件,声明了一个void *operator new( size_t, void *p ) throw() { return p; } 8 #include <cstddef> // for ptrdiff_t, size_t 9 #include <cstdlib> // for exit() 10 #include <climits> // for UINT_MAX 11 #include <iostream> // for cerr 12 13 namespace QY{ 14 // 分配空间(operator new) 15 template <class T> 16 inline T* _allocate(ptrdiff_t size, T*){ 17 std::set_new_handler(0); 18 T *tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); 19 if (tmp == 0) 20 { 21 std::cerr << "out of memory" << std::endl; 22 exit(1); 23 } 24 return tmp; 25 } 26 27 // 回收空间(operator delete) 28 template <class T> 29 inline void _deallocate(T* buffer){ 30 ::operator delete(buffer); 31 } 32 33 // 在指定内存上构造一个对象(new(pMyClass)MyClass();) 34 template <class T1, class T2> 35 inline void _construct(T1* p, const T2& value){ 36 new(p) T1(value); // 创建。placement new. 调用 ctor of T1, 即new(pMyClass)MyClass(); 37 } 38 39 // 析构对象 40 template<class T> 41 inline void _destroy(T* ptr){ 42 ptr->~T(); 43 } 44 45 // 按allocator标准,定义结构 46 template <class T> 47 class allocator{ 48 public: 49 typedef T value_type; 50 typedef T* pointer; 51 typedef const T* const_pointer; 52 typedef T& reference; 53 typedef const T& const_reference; 54 typedef size_t size_type; 55 typedef ptrdiff_t difference_type; 56 57 // 重新绑定分配器(rebind allocator of type U) 58 template <class U> 59 struct rebind 60 { 61 typedef allocator<U> other; 62 }; 63 64 pointer allocate(size_type n, const void* hint=0){ 65 return _allocate((difference_type)n, (pointer)0); 66 } 67 68 void deallocate(pointer p, size_type n){ 69 _deallocate(p); 70 } 71 72 void construct(pointer p, const T& value){ 73 _construct(p, value); 74 } 75 76 void destroy(pointer p){ 77 _destroy(p); 78 } 79 80 pointer address(reference x){ 81 return (pointer)&x; 82 } 83 84 const_pointer address(const_reference x){ 85 return (const_pointer)&x; 86 } 87 88 size_type max_size() const{ 89 return size_type(UINT_MAX / sizeof(T)); 90 } 91 }; 92 } // end of namespace QY 93 94 #endif // __QYALLOC__
1.3 使用这个allocator
1 #include "qyalloc.h" 2 #include <vector> 3 #include <iostream> 4 using namespace std; 5 6 int main(){ 7 int ia[5] = {0, 1, 2, 3, 4}; 8 unsigned int i; 9 10 vector<int, QY::allocator<int> > iv(ia, ia+5); 11 for(i=0; i<iv.size(); i++) 12 cout << iv[i] << ‘ ‘; 13 cout << endl; 14 15 return 0; 16 }
1.4 SGI标准的空间配置器(std::allocator)
符合部分标准,效率不佳,不建议使用。
1.5 SGI特殊的空间配置器(std::alloc)
class Foo{ ... }; Foo* pf = new Foo; // 配置内存,然后构造对象 delete pf; // 将对象析构,然后释放内存
new: (1)调用 ::operator new 配置内存;
(2)调用 Foo::Foo() 构造对象内容。
delete: (1)调用 Foo::~Foo() 将对象析构;
(2)调用 ::operator delete 释放内存。
标签:
原文地址:http://www.cnblogs.com/xiaoqingyang/p/5412137.html