第二章 空间适配器(allocator)

空间适配器(allocator)1.空间配置器的标准接口2.具备次配置力(sub-allocation)的SGI空间配置器3.内存基本处理工具STL的操作对象(所有的数值)都存放在容器之内, 而容器一定需要配置空间以置放资料,所以这时需要到空间适配器。1.空间配置器的标准接口根据STL的规范,以下是allocator的必要接口:allocator: :value_type allocator: :pointer allocator::const_pointerallocator::refere
摘要由CSDN通过智能技术生成


STL的操作对象(所有的数值)都存放在容器之内, 而容器一定需要配置空间以置放资料,所以这时需要到空间适配器。

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, 代表allocator<U>

allocator:: allocator() 
default constructor
 
allocator::allocator(const allocator&) 
copy constructor 

template <class U>allocator::allocator(const allocator<U>&)
泛化的copy constructor allocaLor:: ~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, cosnt 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.1 简单的空间配置器,JJ::allocator

#include<new>
#include<cstddef>
#include<cstdlib>
#include<climits>
#include<iostream>
#include<vector>
using namespace std;

namespace JJ
{
   
	template <class T>
	inline T* _allocate(ptrdiff_t size, T*)

	{
   
		set_new_handler(0);
		T* tmp = (T*)(::new_handler new((size_t)(size * sizeof(T))));
		if (tmp == 0)
		{
   
			cerr << "out of memory" << endl;
			exit(1);
		}
		return tmp;

	}
	template <class T>
	inline void _deallocate(T* buffer) {
   
		::operator delete(buffer);
	}

	template <class T1,class T2>
	inline void _deallocate(T* buffer) {
   
		::operator delete(buffer);
	}

	template <class T1,class T2>
	inline void _construct(T1* p, const T2& value) {
   
		new(p) T1(value);
	}

	template <class>
	inline allocator(T* ptr) {
   
		ptr->~T();
	}

	template <class T>
	class allocator {
   
		public:
			typedef T
			typedef T*
			typedef const T*
			typedef T&
			typedef const T&
			typedef size_t
			typedef ptrdiff_t

			typedef <class U>
			struct rebind {
   
			typedef allocator<U> other;
		};

		pointer allocator(size_type n, const coid* hint = 0) {
   
			return _allocate((difference_type)n, (pointer)0);
		}

		void deallocate(pointer p, size_type n)
		{
   
			_deallocate(p);
		}

		void construct(pointer p, const T& value) {
   
			_construct(p, value);
		}

		void destroy(pointer p)
		{
   
			_destroy(p);
		}

		pointer address(reference x) {
   
			return (pointer)&x;
		}

		const_pointer const_address(const_reference x) {
   
			return (const_pointer)&x;
		}

		size_type max_size()const {
   
			return size_type(UINT_MAX / sizeof(T));
		}
	};
}

//JJ::allocator应用于程序之中,只能有限度搭配PJ STL和RW STL
int main()
{
   
	int ia[5] = {
    0,1,2,3,4 };
	unsigned int i;

	vector<int, JJ::allocator<int> >iv(ia, ia + 5);
	for (i = 0; i < iv.size(); i++)
		cout << iv[i] << ' ' << endl;

}

2.具备次配置力(sub-allocation)的SGI空间配置器

SGI STL的配詈器与众不同, 也与标准规范不同, 其名称是alloc而非allocator, 而且不接受任何参数。换句话说,如果你要在程序中明白采用SGI配置器,则不能采用标准写法:

vector<int,std::allocator<int> >iv;//in VC or CB

必须这样写:

vector<int,std::alloc> iv;//in GCC

SGI STL allocator未能符合标准规格,不会带来困扰,因为通常我们使用缺省的空间配置器,很少需要自行指定配置器名称,而SGI STL的 每一个容器都已经指定其缺省的空间配置器为alloc。 例如下面的vector声明:

template <class T, class Alloc=alloc> //缺省使用alloc为配置器
 class vector {
    ... }; 

2.1 SGI标准的空间配宣器, std ::allocator

SGI也定义有一个符合部分标准、 名为allocator的配置器,不建议使用。 主要原因是效率低, 只把C++的::operator new和::operator delete做一层薄薄的包装而已。下面是SGI的std::allocator全貌:

G++ 2.91.57, cygnus\cygwin-b20\include\g++\defalloc.h完整列表
//我们不赞成包含此文件。这是原始的HP default allocator。提供它只是为了
 //回溯兼容
//
// DO NOT USE THIS FILE 不要使用这个文件,除非你手上的容器是以旧式做法
//完成一—那就需要一个拥有HP-style interface的空间配置器。SGI STL使用
//不同的allocator接口。SGI-style allocators不带有任何与对象型别相关
//的参数; 它们只响应void* 指针(侯捷注: 如果是标准接口, 就会响应一个
// "指向对象型别 的指针,T*)。 此文件并不包含于其它任何SGI STL头文件
#include <new.h> 
#include <stddef.h> 
#include <stdlib.h>
#include <limits.h>
#include <iostream.h>
#include <algobase.h> 
template <class T> 
inline T* allocate(ptrdiff_t size, T*) {
   
set_new_handler(O); 
T* tmp = (T*) (::operator new ((size_t) (size * sizeof (T)))) ;
 if (tmp == 0) {
    
 cerr << "out of memory" << endl;
  exit (1); 
 }
 return tmp;
 }
 template <class T>
 inline void deallocate(T* buffer){
   
 ::operator delete
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值