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

  • 2019 年 10 月 3 日
  • 筆記

最近做一個事情,實現一個流程交互,其中主交互流程函數中,涉及較多的內存申請,

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

使用很多方法,都避免不了較多的出錯分支時,一堆的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;  }