第二章 空间配置器(allocator)

1.空间配置器的标准接口

一般接口(generalized)

allocator::value_type
allocator::pointer
allocator::const_pointer
allocator::reference
allocator::const_reference
allocator::size_type
allocator::difference_type

特殊化接口(specified)

接口接口
allocator::rebind旨在帮助allocator为不同类型的元素分配空间,即使allocator已被指定为一个对象分配空间。
allocator::allocator()默认构造函数
allocator::allocator(const allocator&)拷贝函数
template<class U>allocator::allocator(const allocator<U>&)泛型拷贝函数
allocator::~allocator()默认析构函数
pointer allocator::address(reference x) const返回指定对象的地址,例如:a.address(x) <=> &x
pointer allocator::allocate(size_type n, const void* = 0)配置空间,用来存储n个类型为T的对象,第二个参数主要用于优化内存优化和管理
allocator::deallocate(pointer p, size_type n)释放之前所分配的内存
allocator::allocator::max_size() const返回所成功分配的最大内存大小的值
allocator::destroy(pointer p)等价于 p->T()

用一个例子对allocator::rebind进行补充:

template<class T>
class alloc;

template<typename T, typename Alloc = alloc<T>>
class MyContainer{
public:
    template<typename U>
    struct rebind{
        typedef Alloc<U> other; // Allocator type for type U
        // other represents some other objects
    };
};

2.设计一个简单的空间配置器(Compiler:G++)

#ifndef T_ALLOC_
#define T_ALLOC_

#include <new>          // for placement new
#include <cstddef>      // for ptrdiff_t, size_t
#include <cstdlib>      // for exit()
#include <climits>      // for UINT_MAX
#include <iostream>     // for cerr
#include <vector>       // for test

namespace T_ {
    // allocate memory
    template<class T>
    inline T* _allocate(ptrdiff_t size, T*) {
        std::set_new_handler(0);    // invoke when out of memory
        T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));  // allocate memory 
        if (tmp == 0) {   // the allocated memory is 0, which means that allocating memory fails
            std::cerr << "out of memory" << '\n';
            exit(0);    // terminate processs
        }
        return tmp;     // return the pointer of the allocated memory block
    }

    // release memory
    template<class T>
    inline void _deallocate(T* buffer) {
        ::operator delete(buffer);  // release the allocated memory
    }

    // constructor
    template<class T1, class T2>
    inline void _construct(T1* p, const T2& value) {
        new(p) T1(value);           // assign value at pointer p
    }

    // destructor
    template<class T>
    inline void _destroy(T* ptr) {
        ptr->~T();                  // invoke the destructor of type class
    }

    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;

        /*-----implement part of the specific API-----*/

        // allocator::rebind->rebind allocator of type U
        template<class U>
        struct rebind {
            typedef allocator<U> other;
        };

        // pointer allocator::allocate->hint used for locality
        pointer allocate(size_type n, const void* hint = 0) {
            return _allocate((difference_type)n, (pointer)0);
        }

        // allocator::deallocate
        void deallocate(pointer p, size_type n) { _deallocate(p); }

        // allocator::construct
        void construct(pointer p, const T& value) {
            _construct(p, value);
        }

        // allocator::destroy
        void destroy(pointer p) { _destroy(p); }

        // pointer allocator::address
        pointer address(reference x) { return (pointer)&x; }

        // const_pointer allocator::const_address
        const_pointer const_address(const_reference x) {
            return (const_pointer)&x;
        }

        // size_type allocator::max_size()
        size_type max_size() const {
            return size_type(UINT_MAX / sizeof(T));
        }
    };
}
#endif

int main() {
    int ia[5] = { 0, 1, 2, 3, 4 };
    unsigned int i;

    std::vector<int, T_::allocator<int>> iv(ia, ia + 5);
    for (i = 0; i < iv.size(); i++) std::cout << iv[i] << ' ';
    std::cout << '\n';

    return 0;
}

Related Post

STL源码分析-第一章

第一章 STL概述 可能令你困惑的C++语法 1....

0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
It's late! Remember to rest.
0
希望看到您的想法,请您发表评论x