STL控件配置器allocator

1.自定义控件配置器

#ifndef _JJALLOC_
#define _JJALLOC_

#include <new>          //for placement new (定位new)
#include <cstddef>      //for ptrdif_t,size_t
#include <cstdlib>      //for exit()
#include <climits>      // for UNIT_MAX
#include <iostream>     //for cerr
namespace JJ
{
    //用于分配内存
    template<typename T>
    inline T* _allocate(ptrdiff_t size,T*)
    {

        std::set_new_handler(0);//没有处理无法分配内存的回调函数,即随时可抛出异常
        //分配内存用的是 ::operator new
        T* tmp = (T*)::operator new((size_t)(size * sizeof(T)));
        if(tmp==0)
        {
            std::cerr<<"out of memory"<<std::endl;
            exit(1);
        }
        return tmp;
    }
    //对 ::operator new 分配的内存构造对象
    template<typename T1,typename T2>
    inline void _construct(T1 * p,const T2 & val)
    {
        //构造对象 对operator new 分配的内存不能用构造函数构造对象
        //只能用 new 的定位new(placement new)形式构造对象
        new (p) T1(val);
    }

    //用于 销毁对象
    template <typename T>
    inline void _destory(T *p)
    {
        p->~T();
    }
    //用于 释放内存
    template <typename T>
    inline void _deallocate(T* p)
    {
        ::operator delete(p);
    }

    template<typename 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;
        //rebind allocator of type U
        template<typename U>
        struct rebind
        {
            typedef allocator<U> other;
        };
        //分配内存
        pointer allocate(size_type n,const void* hint=0)
        {
            std::cout<<"分配内存"<< std::endl;
            return _allocate((difference_type)n,(pointer)0);
        }
        //构造对象,这里construct与destory要不要都行
        //因为全局函数construct()与destory()定义在stl_construct.h中
        void construct(pointer *p,const T&val)
        {
              std::cout<<"构造对象"<< std::endl;
              _construct(p,val);
        }
        //销毁对象
        void destroy(pointer *p)
        {
              std::cout<<"销毁对象"<< std::endl;
            _destory(p);
        }
        //释放内存
        void deallocate(pointer p,size_type n)
        {
              std::cout<<"释放内存"<< std::endl;
            _deallocate(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

2 上述代码重要点

  1>将内存配置与对象构造分开,将对象析构与内存释放分开。这也是标准空间配置器的思想。
   
    2>内存分配用的函数::operator new,类似malloc,实现内存的分配但不构造对象。对应的,内存释放用::operator delete。
  
  3>对象构造用定位new(placement new);对象销毁用析构函数即可。
 

 3 测试

 
#include <iostream>
#include <vector>
#include <string>
#include "2jjalloc.h"
using namespace std;
int main()
{
    vector<string,JJ::allocator<string>> vi={"Hello","World"};
   
    for(int i=0;i<vi.size();++i)
    cout<<vi[i]<<endl;
    return 0;
}



测试结果:



注意:
标准配置器定义于memory中,而空间配置器与负责对象构造和析构的函数是分开的。配置器定义在stl_alloc.h中,stl_construct.h中定义全局函数construct和destory函数负责对象的构造与析构。
问题是:在上面例子中,我重载了函数construct与destory,但是没有执行?

还有一个发现:
当上例子中,将函数allocate与deallocate换个函数名时,运行会报错:




解释:








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值