最近做一個事情,實現一個流程交互,其中主交互流程函數中,涉及較多的內存申請,
而健康的函數,都是在函數退出前將手動申請不再需要的內存釋放掉,
使用很多方法,都避免不了較多的出錯分支時,一堆的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; }