C++STL学习(12)STL深入(1) 设计简单的空间配置器

注:博客内容均来自于对《STL源码剖析》侯捷,华中科技大学出版社一书的笔记。转载请注明出处。

所有例程在Dev-C++上编译运行,编译选择的是GUN C++11。


1、写在前面


       从本篇博客开始,对STL进行更深入的学习。博客内容来源对《STL源码剖析》学习的笔记。其中的个人看法和理解,肯定会存在不妥之处。如果觉得不妥,敬请留言指正。相互交流,探讨,学习才能共同进步。微笑


2、空间配置器


         空间配置器在STL中的作用就是在为各个容器分配必要的内存空间。它默默的工作在程序的背后,是各种容器正常工作的必要基础。


3、空间配置器在哪


STL中的容器vector为例,vector的原型是这样子的:

template <class T, class Alloc = alloc>

class vector

{

         //省略

};

在一般使用的时候我们都没有去理会第二个泛型的传入。vector的使用可看前面的博客:

C++STL学习(1)容器vector

Tips:

  在STL的使用中,给出的构造函数都是不带第二个参数的,见下图(来自上面链接的内容)。


  从vector的定义原型上可以推测,我们按照要求的空间配置器接口传入一个我们自己设计的空间配置器在理论上也是能行得通的。


4、设计空间配置器



  要想设计出一个可以“接入”到程序中的空间配置器,首先要知道空间配置器的必要的接口是什么样子的以及它要提供哪些功能。


4.1 STL中空间配置器的标准接口



    STL中空间配置器的标准接口包含必要的数据类型和必要的接口函数。

必要的数据类型:

typedef T             value_type;

typedef T*           pointer;

typedefconst T*   const_pointer;

typedefT&           reference;

typedefconst T&  const_reference;

typedefsize_t       size_type;

typedefptrdiff_t   difference_type;

必要的接口函数有:

allocator::rebuild

allocator::allocator                                 默认构造函数

allocator::allocator(constallocator&)      拷贝构造函数

template<classU> allocator::allocator(const allocator<U>&)  泛型拷贝构造函数

allocator::~allocator()            默认的析构函数

pointerallocator::address()    返回某个对象地址

pointerallocator::address(const_reference x) const                  返回某个常量对象的地址

pointer  allocator::allocate(size_type n, const void*hint=0)     配置空间

void  allocator::deallocate(pointer p, size_type n)                   释放配置过的空间

size_typeallocator::max_size() const                                       返回可配置的最大值

voidallocator::constrct(pointer p, const T& value)                   开辟内存

voidallocator::destroy(pointer p)                                              释放内存


4.2  设计空间配置器


有了上面的基础就可以根据接口来设计一个自己的空间配置器了。

ex2.h

#ifndef __ALLOC_H
#define __ALLOC_H

#include <new>			//new
#include <cstddef>		//ptrdiff_t, size_t
#include <cstdlib>		//exit
#include <climits>		//UNIT_MAX
#include <iostream>		//cerr


namespace RB
{
	using namespace std;
	
	//分配内存
	template<class T>
	inline T* _allocate(ptrdiff_t size, T*)
	{
		set_new_handler(0);
		T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
		if(tmp == 0)
		{
			cerr << "out of memery" << 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);
	}
	
	//销毁
	template<class T>
	inline void _destory(T* ptr)
	{
		ptr->~T();
	}
	
	template<class T>
	class alloctor
	{
	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;
		
		template<class U>
		struct rebuild
		{
			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 constrct(pointer p, const T& value)
		{
			_construct(p, value);
		}
		
		//销毁
		void destroy(pointer p)
		{
			_destroy(p);
		}
		
		//返回某个对象的地址,等价:&x
		pointer address(reference x)
		{
			return (pointer)&x;
		}
		
		//返回某个const对象的地址,等价:&x
		const_pointer const_address(const_reference x)
		{
			(const_pointer)&x;
		}
		
		//返回可成功配置的最大量
		size_type max_size() const
		{
			return size_type(UINT_MAX/sizeof(T)); 
		}
		
	};

}//end of namespace RB 


#endif

5、使用自己设计的空间配置器


   简单的使用一下我们自己设计的空间配置器。因为空间配置器是工作在背后的,因此使用的时候,我们是不用关注到底用了什么空间。写一个简单的小程序试试:

#include "ex2.h"
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;

int main()
{
	vector<int, RB::allocator<int> > iv;
	for(int i=0; i<10; ++i)
		iv.push_back(i);
		
	copy(iv.begin(), iv.end(), std::ostream_iterator<int>(cout, " "));
	
	cout << endl;
}

运行结果:



从使用和运行上来看,相比使用默认的空间配置器并无很大的差异。着说明我们自己设计的空间配置器确实是运行起来了的。








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空空的司马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值