1. 程式人生 > >C++STL 空間配置器allocator

C++STL 空間配置器allocator

先來介紹一下STL的六大元件

1. 空間配置器:記憶體池實現小塊記憶體分配,對應到設計模式--單例模式(工具類,提供服務,一個程式只需要一個空間配置器即可),享元模式(小塊記憶體統一由記憶體池進行管理)

2.迭代器:迭代器模式,模板方法

3.容器:STL的核心之一,其他元件圍繞容器進行工作:迭代器提供訪問方式,空間配置器提供容器記憶體分配,演算法對容器中資料進行處理,仿函式偽演算法提供具體的策略,型別萃取  實現對自定義型別內部型別提取。保證演算法覆蓋性。其中涉及到的設計模式:組合模式(樹形結構),門面模式(外部介面提供),介面卡模式(stack,queue通過deque適配得  到),建造者模式(不同型別樹的建立過程)。

4.型別萃取:基於範型程式設計的內部型別解析,通過typename獲取。可以獲取迭代器內部型別value_type,Poter,Reference等。

5.仿函式:一種類似於函式指標的可回撥機制,用於演算法中的決策處理。涉及:策略模式,模板方法。

6介面卡:STL中的stack,queue通過雙端佇列deque適配實現,map,set通過RB-Tree適配實現。涉及介面卡模式。

空間配置器:

一般來說,我們使用C++ new操作符主要進行兩步操作:

(1)::operator new分配記憶體

(2)呼叫建構函式構造物件

而使用C++ delete操作符主要進行兩步操作:

(1)呼叫解構函式析構物件

(2)::operator delete釋放記憶體

STL將記憶體分配與物件構造析構分開,因此空間配置器分為記憶體分配及空間初始化。


程式碼實現:

#include<iostream>
#include<functional>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
using namespace std;


// STL

/*
1.一級空間配置器
2.二級空間配置器
開闢的記憶體 大於128 一級空間配置器
malloc free
二級空間配置器
記憶體池
*/
/*
空間配置器

/*
1.物件的生成有幾步
1.開闢空間 operator new
2.呼叫建構函式
2.物件的銷燬
1.呼叫解構函式
2.釋放空間 operator delete
*/
namespace LY1206
{
	template<typename T>
	T* _allocate(ptrdiff_t size, T*)
	{
		set_new_handler(0);
		T* tmp = (T*)(::operator new((size_t)size*sizeof(T)));
		if (tmp == NULL)
		{
			cout << "out of memory!" << endl;
			exit(0);
		}
		return tmp;
	}
	template<typename T1, typename T2>
	void _construct(T1* p, const T2& value)
	{
		/*
		p  ==> T2
		*/
		new (p)T2(value);
	}
	template<typename T>
	void _deallocate(T* p)
	{
		::operator delete(p);
	}
	template<typename T>
	void _destory(T* p)
	{
		p->~T();
	}
	template<typename T>
	class MyAllocate
	{
	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<typename U>
		struct rebind
		{
			typedef MyAllocate<U> other;
		};
		pointer allocate(size_type size, const void* hint = 0)
		{
			return _allocate(size, (pointer)0);
		}
		void deallocate(pointer p, size_type n)
		{
			_deallocate(p);
		}
		void construct(pointer p, const_reference val)
		{
			_construct(p, val);
		}
		void destory(pointer p)
		{
			_destory(p);
		}
	};
};

int main()
{
	vector<int, LY1206::MyAllocate<int>> vec;
	int arr[] = { 23, 54, 12, 31, 32, 113, 2 };
	int len = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < len; ++i)
	{
		vec.push_back(arr[i]);
	}
	vector<int, LY1206::MyAllocate<int>>::iterator it = vec.begin();
	for (it; it != vec.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;

	return 0;
}

執行結果: