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;