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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM