一个简单的空间配置器

_STL_jjalloc.h

#pragma once
#ifndef _JJALLOC_
#define _JJALLOC_
#include <iostream>
#include <cstdlib>
#include <new>

namespace JJ
{
    //配置空间,size是要分配的元素个数,第二个参数用处不清楚
    template <class T>
    inline T* _allocate(ptrdiff_t size, T*)
    {
        /*
        set_new_handler是一个输入并返回new_handler类型的函数。set_new_handler的输入参数是operator new分配
        内存失败时要调用的出错处理函数的指针,返回值是set_new_handler没调用之前就已经在起作用的旧的出错处理
        函数的指针.new_handler是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数,用于处理
        分配内存时出现的异常
        */
        set_new_handler(0);
        /*
        new:运算符,有new和::new之分,前者位于std
        operator 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运算符中完成的
        */
        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)
    {
        //在指针p所指向的内存空间创建一个类型为T1的对象,调用的构造函数接受一个类型为const T2&
        //(或其他兼容类型)的参数
        //如果想在预分配的内存上创建对象,用缺省的new操作符行不通,可以用placement new构造,它允许你构造一个新对象
        //到预分配的内存上
        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;
        };

        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));
        }
    };
}
#endif

测试程序:

#include "_STL_jjalloc.h"
#include <iostream>

using namespace std;

class Test
{
public:
    int x;
    Test(int b = 0) 
    {
        x = b;
    }
    ~Test() {}
};
int main()
{
    int x = 4;
    JJ::allocator<int> a;
    JJ::allocator<Test> b;
    //分配内存
    int *p = a.allocate(1);
    Test *t = new Test;
    b.construct(t, x);
    *p = 1;
    cout << *p << endl;//1
    cout << t->x << endl;//4
    cout << *(a.address(x)) << endl;//4
    cout << a.max_size() << endl;
    b.destroy(t);
    a.deallocate(p, 1);
    system("pause");
    return 0;
}

 

posted @ 2015-11-04 14:45  合唱团abc  阅读(380)  评论(0编辑  收藏  举报