STL源码剖析-实现自定义的allocator

为什么需要allocator

整个stl的操作对象都是在容器中,而容易一定需要配置空间存放对象,我们通常使用容器的时候没有关心内存是如何分配的,者就是这篇文章要介绍的。

这是vector头文件的定义

template<
    class T,
    class Allocator = std::allocator
> class vector;

可以看到在我们定义vector时,若没传allocator会使用默认的std::allocator,下面可以按照allocator的定义规范实现一个简单的空间配置器,空间可以是内存,共享内存、磁盘存储。

空间配置器的标准接口

根据STL的规范,allocator的必要接口

  • 各种typedef
allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type
allocator::rebind // class rebind拥有唯一成员other;是一个typedef,代表allocator
  • 初始化,地址相关函数
// 配置空间,足以存储n个T对象,第二个参数是提示,能增进区域性
pointer allocator::allocate(size_type n, const void*=0)
size_type allocator::max_size() const
pointer allocator::address(reference x) const
const_pointer allocator::address(const_reference x) const
  • 构建函数
void allocator::construct(pointer p, const T& x)
void allocator::destory(pointer p)

自定义allocator

定义allocator.h

#include 
#include 
#include  // for exit()
#include  // for UNIX_MAX
#include 

namespace test {

template
inline T* _allocate(ptrdiff_t size, T*) {
    std::cout << "_allocate called" << std::endl;
    set_new_handler(0);
    T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
    if (NULL == tmp) {
        std::cerr << "out of memory" << std::endl;
        exit(0);
    }
    return tmp;
}

template
inline void _deallocate(T* p) {
    ::operator delete(p);
}

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

template
inline void _destroy(T* p) {
    p->~T();
}

template
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
    struct rebind
    {
        typedef Allocator other;
    };

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

    void deallocate(pointer p, size_type n) {
        return _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 address(const_reference x) {
        return (const_pointer)&x;
    }

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

} // end of namespace

在容器中使用上面自定义的allocator

#include "allocator.h"

#include 

using namespace std;

int main(int argc, char const *argv[])
{
    cout << "allocator test" << endl;
    vector > v;
    v.push_back(1);
    v.push_back(2);
    for (int i = 0; i < v.size(); ++i)
    {
        cout << v[i] << endl;
    }

    return 0;
}

输出结果

allocator test
_allocate called
_allocate called
1
2

你可能感兴趣的:(STL源码剖析-实现自定义的allocator)