C++ allocator类学习理解

1. 介绍

一般情况下,将内存分配和对象构造组合在一起可能会导致不必要的浪费(有些对象可能用不了那么多的内存)。在此情况下,我们希望将内存分配和对象构造分离。这意味着我们可以按需分配内存,但只在真正需要时才真正执行对象的内存扩充操作(同时付出一定开销)。常见的容器vector的内存分配就是这种方案。

  • 标准库allocator类定义在头文件memory中,它帮助我们将内存分配和对象构造分离开来。

2. 主要成员函数

  • allocate
pointer allocate(size_type n);

分配存储块;尝试分配n个T个类型的存储空间,然后返回第一个元素的起始地址;只分配空间,不构造对象

  • construct
void construct(U* p, T a);

在p所指内存中构造一个T类型的对象a

  • destory
void destroy (T* p);

调用析构函数销毁p所指的对象,但不会释放空间,也就意味着,这段空间依然可以使用

  • deallocate
void deallocate(pointer p, size_t n);

释放先前allocate分配的且没有被释放的存储空间,意味着回收空间
p:指向以前使用allocator :: allocate分配的存储块的指针。
n:在调用allocator :: allocate时为这个存储块分配的元素数量。

3. 使用步骤

  1. allocator与类绑定,因为allocator是一个泛型类
  2. allocate()申请指定大小空间
  3. construct()构建对象,其参数为可变参数,所以可以选择匹配的构造函数
  4. 使用,与其它指针使用无异
  5. destroy()析构对象,此时空间还是可以使用
  6. deallocate()回收空间

4. 实例使用

  • m_vector.h
#include<iostream>
#include<memory>
using std::cout;
using std::endl;

template<typename Tp>
class Vector
{
public:
    Vector():_elems(NULL),_first_free(NULL),_end(NULL){}

    ~Vector()
    {
        if(_elems){
            while(_elems!=_first_free)
                _alloc.destroy(--_first_free);
            _alloc.deallocate(_elems,capacity());
        }
    }

    void push_back(const Tp& value)
    {
        if(size()==capacity())
            reallocate();
        _alloc.construct(_first_free++,value);
    }

    void pop_back()
    {
        if(size()>0)
        {
            _alloc.destory(--_first_free);
        }
    }
    
    size_t size() const
    {
        return _first_free-_elems;
    }

    size_t capacity() const
    {
        return _end-_elems;
    }

    Tp & operator[](size_t idx)
    {
        return _elems[idx];
    }


private:
    static std::allocator<Tp> _alloc;
    Tp* _elems;
    Tp* _first_free;
    Tp* _end;
    void reallocate()
    {
        size_t oldCapacity=capacity();  
        size_t newCapacity = oldCapacity==0?1:oldCapacity*2;

        Tp* newElems=_alloc.allocate(newCapacity);
        if(_elems){
            std::uninitialized_copy(_elems,_first_free,newElems);
            while(_elems!=_first_free)
                _alloc.destroy(--_first_free);
            _alloc.deallocate(_elems,oldCapacity);   
        }
        _elems=newElems;
        _first_free=_elems+oldCapacity;
        _end=_elems+newCapacity;
    }
};

template<typename Tp>
std::allocator<Tp> Vector<Tp>::_alloc;  //构造实例

void display(Vector<int> & vec)
{
    cout<<"vec's size= "<<vec.size()<<endl;
    cout<<"vec's capacity= "<<vec.capacity()<<endl;
}

  • main.cpp
#include<iostream>
#include"m_vector.h" 
using std::cout;
using std::endl;
int main(int argc,char** argv)
{
    Vector<int> VecInt;
    display(VecInt);
    VecInt.push_back(1);
    display(VecInt);
    VecInt.push_back(2);
    display(VecInt);
    VecInt.push_back(3);
    display(VecInt);
    VecInt.push_back(4);
    display(VecInt);
    VecInt.push_back(5);
    display(VecInt);
    VecInt.push_back(6);
    display(VecInt);
    VecInt.push_back(7);
    display(VecInt);

    for(size_t idx=0;idx!=VecInt.size();++idx)
    {
        cout<<VecInt[idx]<<" ";
    }
    cout<<endl;
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值