空间配置器

        为什么不说allocator是内存配置器而说它是空间配置器?因为空间不一定是内存,空间也可以是磁盘或其他辅助存储介质。你可以写一个allocator直接向硬盘取空间。

set_new_handler:

        当operator new申请一个内存失败的时候,会调用set_new_handler设置的函数,参数为0,则抛出异常 。

new运算符和operator new()

        operator new():指对new的重载形式,它是一个函数,并不是运算符。对于operator new来说,分为全局重载和类重载,全局重载是void* ::operator new(size_t size),在类中重载形式 void* A::operator new(size_t size)。还要注意的是这里的operator new()完成的操作一般只是分配内存,事实上系统默认的全局::operator new(size_t size)也只是调用malloc分配内存,并且返回一个void*指针。而构造函数的调用(如果需要)是在new运算符中完成的。

int * aptr = new int(10);
delete aptr, aptr = nullptr;

        上面的代码是我们最基本也是最常见的使用new和delete的方式,当编译器运行int * aptr = new int(10); 这行代码时,其实是分为两个步骤来执行,第一步,调用operator new(size_t size) 分配内存;第二步在分配的内存上调用placement new(void * ptr) T(); “定位放置 new”,就是把对象构建在指定的ptr指向的内存上,换句话就是在指定的内存上调用构造函数。

#ifndef _JJALLOC_  
#define _JJALLOC_  
#include<new>//for placement new  
#include<cstdlib>//for ptrdiff_t,size_t  
#include<climits>//for UINT_MAX  
#include<iostream>//for cerr  

namespace JJ
{

	template<class T>
	inline T* _allocate(ptrdiff_t size, T*){
		//当operator new申请一个内存失败的时候,会调用set_new_handler设置的函数
		//参数为0,则抛出异常  
		set_new_handler(0);
		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(buffer);
	}

	template<class T1, class T2>
	inline void _construct(T1*p, const T2& value){
		new(p)T1(value);
		//这叫place   new,在指针p所指向的内存空间创建一个类型为T1的对象。
		//调用的构造函数接受一个类型为const   T2&(或其他兼容类型)的参数
	}
	template<class T>
	inline void _destroy(T* ptr){
		ptr->~T();
	}

	template<class T>
	class allocator{
	public:
		typedef T           value_type;
		typedef T*          pointer;
		typedef const T*    const_pointer;
		typedef T&          reference;
		typedef const T&    const_reference;
		typedef size_t      size_type;
		typedef ptrdiff_t   difference_type;

		//rebind allocator of type U  
		template<class U>
		struct rebind{
			typedef allocator<U> other;
		};

		pointer allocate(size_type n, const void* 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););
		};
	};

} //end of namespace JJ  
#endif _JJALLOC_ 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值