STL 配置器allocator 实现vector类


前言

配置器的功能在于定义类中内存的分配,一般情况下程序员是不会自定义内存的分类的。


一.STL allocator配置器详解

allocator是STL中非常重要的配置器,用于配置空间内存,在各种Containers中都存在,只是我们在使用时,allocator对我们来说完全是透明的。

1.在容器中感受allocator
//deque get_allocator
void test1(){
    deque<int> mydeque;
    int *p = mydeque.get_allocator().allocate(5);

    for (int i = 0; i < 5; i++){
        mydeque.get_allocator().construct(&p[i], i);
        cout << p[i] << endl;
    }
    
    mydeque.get_allocator().destroy(p);

    mydeque.get_allocator().deallocate(p, 5);
    p = NULL;
}


//map get_allocator
void test2(){
    map<char, int> mymap;
    pair<const char,int> *p = mymap.get_allocator().allocate(4);
    
    for (int i = 0; i < 4; i++){
        mymap.get_allocator().construct(&p[i], make_pair('a' , 1));
        cout << p->first << ", " << p->second << endl;
    }

    mymap.get_allocator().destroy(p);

    mymap.get_allocator().deallocate(p, 4);
}

2.std::allocator的基本用法
void test3(){
    std::allocator<int> a1;
    int *p1 = a1.allocate(3);
    a1.construct(&p1[0], 100);
    a1.construct(&p1[1], 200);
    a1.construct(&p1[2], 300);
    cout << p1[0] << endl;
    cout << p1[1] << endl;
    cout << p1[2] << endl;
    a1.destroy(p1);//析构p1指向的对象
    cout << "----------after destory-----------" << endl;
    cout << p1[0] << endl;
    cout << p1[1] << endl;
    cout << p1[2] << endl;
    
    a1.deallocate(p1, 1);
}

3.std::allocator的泛型编程
template<typename T>
void test4(const T& val){
    allocator<T> a1;
    T *p = a1.allocate(1);
    a1.construct(p, val);
    cout << *p << endl;
    a1.destroy(p);
    a1.deallocate(p, 1);
    
}

4.allocator配置类类型

注意:
reserve 与 resize:
1.在进行reserve申请空间的时候,对象并没有初始化,只是单纯的申请空间
2.而在进行resize的时候,则是会调用构造函数初始化类

copy 与 uninitialized_copy
1.copy调用=运算符
2.uninitialized_copy 调用const X& 拷贝运算符

class X
{
public:
    X() : _data(0) { cout << "X()" << endl; }
    X(int x) : _data(x) { cout << "X(int)" << endl; }

    X(const X &rhs)
        : _data(rhs._data)
    {
        cout << "X(const X & )" << endl;
    }

    X& operator=(const X& lhs){
        cout << "operator=()" << endl;
        _data = lhs._data;
        return *this;
    }

    operator int()
    {
        return _data;
    }

    ~X() { _data = 0; cout << "~X()" << endl; }

private:
    int _data;
};


/*


*/

void test0()
{
    vector<X> vec1;
    vec1.reserve(10);
    vec1.resize(3);
    vec1[0] = 1;
    vec1[1] = 2;
    vec1[2] = 3;
    cout << "----------" << endl;


    allocator<X> a;
    X *p = a.allocate(3);
    
    // std::copy(vec1.begin(), vec1.end(), p);
    // std::uninitialized_copy(vec1.begin(), vec1.end(), p);
    cout << p[1] << endl;


}


void test1()
{
    allocator<X> alloc;
    X *arr = alloc.allocate(3);
    arr[0] = X(1);
    arr[1] = X(2);
    arr[2] = X(3);

    cout << arr[0] << endl;
    cout << arr[1] << endl;
    cout << arr[2] << endl;
    alloc.destroy(arr);//析构arr指向的对象
    alloc.destroy(arr+1);
    alloc.destroy(arr+2);
    cout << "-------------------------after destroy" << endl;

    cout << arr[0] << endl;
    cout << arr[1] << endl;
    cout << arr[2] << endl;

    alloc.deallocate(arr, 3);
}


二.通过allocator实现Vector类

仿照sgi_stl 中的 stl_vector.h简单实现自己的Vector类

#include <iostream>
#include <memory>
#include <string.h>
using std::allocator;
using std::cout;
using std::endl;
/*
仿照sgi_stl 中的 stl_vector.h
简单实现自己的Vector类

*/

template <typename T>
class MyVector
{
public:
    MyVector(size_t n = 0);
    ~MyVector();

    const T *begin() const { return _begin; }
    const T *end() const { return _end; }
    ptrdiff_t size() const { return _end - _begin; }
    ptrdiff_t capacity() const { return _endCapacity - _begin; }

    T &operator[](int idx) const { return _begin[idx]; }
    void push_back(const T &);
    void pop_back();

private:
    void reallocVector();

private:
    T *_begin;
    T *_end;
    T *_endCapacity;
    static allocator<T> _alloc;
};

template <typename T>
allocator<T> MyVector<T>::_alloc;

/**********************************************************/
template <typename T>
MyVector<T>::MyVector(size_t n)
{
    cout << "MyVector()" << endl;
    _begin = _alloc.allocate(n);
    _end = _begin + n;
    _endCapacity = _begin + n;
}

template <typename T>
MyVector<T>::~MyVector()
{
    cout << "~MyVector()" << endl;
    _alloc.destroy(_begin);
    _alloc.deallocate(_begin, capacity());
    _begin = NULL;
    _end = NULL;
    _endCapacity = NULL;
}

template <typename T>
void MyVector<T>::push_back(const T &ele)
{
    if (size() == capacity())
    {
        reallocVector();
    }

    _alloc.construct(_end++, ele);
}

template <typename T>
void MyVector<T>::pop_back()
{
    if (size() == 0)
    {
        return;
    }
    _alloc.destroy(--_end);
}

template <typename T>
void MyVector<T>::reallocVector()
{
    cout << "reallocVector" << endl;
    size_t newCapacity = (size()==0)? 1:size() * 2;
    T *temp = _alloc.allocate(newCapacity);
    memcpy(temp, _begin, size() * sizeof(T));
    
    auto it = begin();
    while(it!=_end){
        _alloc.destroy(it);
        it++;
    }
    _alloc.deallocate(_begin, capacity());
    

    _begin = temp;
    _end = _begin + newCapacity / 2;
    _endCapacity = _begin + newCapacity;

    temp = NULL;
    
}

int main()
{
    MyVector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    cout << vec[0] << endl;
    cout << vec[1] << endl;

    cout << "size:" << vec.size() << endl;     
    cout << "capacity:" << vec.capacity() << endl;     
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值