C++函數中,兩個自動釋放內存的動態內存申請類

C++函數中,兩個自動釋放內存的動態內存申請類
最近做一個事情,實現一個流程交互,其中主交互流程函數中,涉及較多的內存申請,

而健康的函數,都是在函數退出前將手動申請不再需要的內存釋放掉,

使用很多方法,都避免不了較多的出錯分支時,一堆的if free/delete,代碼長而且不好管理

因此,利用C++對象離開作用域會自動調用析構函數的特點,在這兒實現了兩個自動釋放內存的動態內存申請類

第一個類,只管理內存,不併管理對象

複製代碼

include

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;

}
複製代碼
原文地址https://www.cnblogs.com/eaglexmw/p/11405424.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章