您的位置:首页 > 其它

STL深入剖析——————第二章:空间配置器

2014-05-12 16:10 411 查看
本章主要是空间配置器,一般我们都不用管的。不过弄懂这个对接下来的很多内容都可以搞懂,这个还可以提高STL的效率。

下面是allocator的必要接口:

allocator::value_type

allocator::pointer

allocator::const_pointer

allocator::reference

allocator::const_reference

allocator::size_type

allocator::difference_type

allocator::rebind

allocator::allocator()

allocator::allocator(const allocator&)

template<class U>allocator::allocator(const allocator<U>&)

allocator::~allocator()

pointer allocator::address(reference x)const

const_pointer allocator::address(const_reference x)const

pointer allocator::allocate(size_tyoe n, const void* = 0)

void allocator::deallocate(pointer p, size_type n)

size_type allocator::max_size() const

void allocator::construct(pointer p, const T& x)

void allocator::destroy(pointer p)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

根据上面的接口设计一个简单的控件配置器

生成两个文件jjalloc.h和main.cpp

////////////////////////////////

jjalloc.h

#pragma once

#include <new>

#include <cstddef>

#include <cstdlib>

#include <climits>

#include <iostream>

namespace JJ

{

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 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);

}

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;

template <class U>

struct rebind

{

typedef allocator<U> other;

};

allocator()

{

return;

}

template <class U>

allocator(const allocator<U>& c)

{

}

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));

}

};

}

/////////////////////////////////////////////////////

main.cpp的

#include "jjalloc.h"

#include <vector>

#include <iostream>

using namespace std;

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;

}

}

以上代码为了在VS2010下面运行,在源代码的基础上加上了拷贝构造函数。

下面我就浅要的分析一下这段代码的含义吧。

先介绍一下,基本上很少用到的函数。

set_new_handler函数:当运算符找不到足够大的连续内存来为对象分配内存时调用这个函数。会自动抛出异常。

这段代码简单的构建出了一个容器的基本框架。容器的基本写法就是用泛函数写的。大量的template。allocator类

主要应用与容器的内存管理。在分配对象时,从这个池来获取,而不是使用new。在某种情况下,这种高度自定义的

内存管理能极大地提高程序效率。

STL标准规格告诉我们。配置器定义于<memory>之中

#include<stl_alloc.h> //负责内存空间的配置与释放

#include<stl_construct.h> //负责对象内容的构造与析构

std::alloc设计思想如下:

1.向system heap要求空间

2.考虑多线程状态

3.考虑内存不足时的应变措施

4.考虑过多"小型区块"可能造成的内存碎片问题

第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器。

当配置区块小于128bytes时,视之为"过小",为了降低额外负担,便采用复杂的memory pool整理方式。

汗,写到这里感觉有点照本宣科的意思~。自己也感觉一知半解。不过总的来说就是属于内存分配这部分。

看了这一部分的内容。感觉可以用这个来做消息队列。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: