zoukankan      html  css  js  c++  java
  • C++函数中,两个自动释放内存的动态内存申请类

    最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请,

    而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉,

    使用很多方法,都避免不了较多的出错分支时,一堆的if free/delete,代码长而且不好管理

    因此,利用C++对象离开作用域会自动调用析构函数的特点,在这儿实现了两个自动释放内存的动态内存申请类

    第一个类,只管理内存,不并管理对象

    #include <vector>
    
    class XAutoFreeMem
    {
    protected:
        std::vector<void*> vec_memorys_;
    
    public:
        XAutoFreeMem::XAutoFreeMem() {};
    
        virtual XAutoFreeMem::~XAutoFreeMem()
        {
            //释放对象时,释放管理的内存
            for(auto item : vec_memorys_){
                free(item);
            }
        }
    
        //通过此接口来申请内存
        void* malloc_mem(unsigned int nsize) 
        {
            void* ptr = malloc(nsize);
            if (nullptr != ptr) {
                vec_memorys_.push_back(ptr);
            }
            return ptr;
        }
    };

    第二个类,能够同时支持内存管理、对象管理

    typedef void (*delete_obj_func)(void*);
    
    class XAutoFreeObject : public XAutoFreeMem
    {
    private:
    
        typedef struct object_manager_st
        {
            void* obj_this;
            delete_obj_func delete_ptr;
        }object_manager_st;
    
    protected:
        template<typename T>
        static void free_object(T* p_this)
        {
            delete p_this;
        }
        template<typename T>
        static void free_objects(T* p_this)
        {
            delete []p_this;
        }
    
    protected:
        std::vector<object_manager_st> vec_objects_;
    
    public:
        XAutoFreeObject::XAutoFreeObject() {};
    
        virtual XAutoFreeObject::~XAutoFreeObject()
        {
            //释放对象时,释放管理的对象
            for(auto item : vec_objects_){
                (*item.delete_ptr)(item.obj_this);
            }
        }
    
        //对象
    
        //通过此接口来创建对象
        template<typename T>
        void new_object(T** ppObj) 
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T;
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            *ppObj = (T*)(stObjMan.obj_this);
            return;
        }
    
        //通过此接口来创建对象
        template<typename T, typename P>
        void new_object_with_param(T** ppObj, P param)
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T(param);
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr = & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            *ppObj = (T*)(stObjMan.obj_this);
            return;
        }
    
        //通过此接口来创建对象,这几个接口使用会麻烦一些,使用示例:std::string* pstr = stAutoManager.new_object<std::string> ();
        template<typename T>
        T* new_object() 
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T;
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            return (T*)(stObjMan.obj_this);
        }
    
        //通过此接口来创建对象
        template<typename T, typename P>
        T* new_object_with_param(P param)
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T(param);
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr = & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            return (T*)(stObjMan.obj_this);
        }
    
        //对象数组
    
        //通过此接口来创建对象数组
        template<typename T>
        void new_objects(T** ppObj, int num) 
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T[num];
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr =(delete_obj_func) & free_objects<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            *ppObj = (T*)(stObjMan.obj_this);
            return;
        }
    
        //通过此接口来创建对象数组
        template<typename T, typename P>
        void new_objects_with_param(T** ppObj, int num, P param)
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T[num](param);
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr = & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            *ppObj = (T*)(stObjMan.obj_this);
            return;
        }
    
        //通过此接口来创建对象数组
        template<typename T>
        T* new_objects(int num) 
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T[num];
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr =(delete_obj_func) & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            return (T*)(stObjMan.obj_this);
        }
    
        //通过此接口来创建对象数组
        template<typename T, typename P>
        T* new_objects_with_param(int num, P param)
        {
            object_manager_st stObjMan;
            stObjMan.obj_this = new T[num](param);
            if (nullptr != stObjMan.obj_this) {
                //取得函数指针
                stObjMan.delete_ptr = & free_object<T>;
                //保存之
                vec_objects_.push_back(stObjMan);
            }
            return (T*)(stObjMan.obj_this);
        }
    };

    调用示例如下:

    int main(int argc, char* argv[])
    {
        //cwSL3D_test_sum();//测试能否成功调用所有接口
        XAutoFreeObject stAutoManager;
    
        char* strMem = (char*)stAutoManager.malloc_mem(100);
    
        std::string* pstr = stAutoManager.new_object<std::string> ();
    
        std::string* pstr2 = nullptr;
        stAutoManager.new_object(&pstr2);
        {
            std::vector<int>* pvec = nullptr;
            stAutoManager.new_object(&pvec);
    
            std::vector<int>* pvec2 = nullptr;
            stAutoManager.new_objects(&pvec, 2);
        }
        return 0;
    }
  • 相关阅读:
    Oracle 游标
    对"com1"的访问被拒绝
    几种不伤身体的速效减肥秘方 生活至上,美容至尚!
    护肤必备,教你如何护理肌肤 生活至上,美容至尚!
    九种食物摆脱便秘烦恼 生活至上,美容至尚!
    1个多月就能看到效果的减肥大法 生活至上,美容至尚!
    防晒涂抹四大要领,让你远离日晒痛苦 生活至上,美容至尚!
    晚间保养四部曲 轻松护肤有妙招 生活至上,美容至尚!
    夏日驱蚊虫蟑螂的最好办法! 生活至上,美容至尚!
    睡前一分钟打造完美下半身 生活至上,美容至尚!
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/11405424.html
Copyright © 2011-2022 走看看