C++函数中,两个自动释放内存的动态内存申请类

简介: C++函数中,两个自动释放内存的动态内存申请类最近做一个事情,实现一个流程交互,其中主交互流程函数中,涉及较多的内存申请,而健康的函数,都是在函数退出前将手动申请不再需要的内存释放掉,使用很多方法,都避免不了较多的出错分支时,一堆的if free/delete,代码长而且不好管理因此,利用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

相关文章
|
3天前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
3天前
|
程序员 编译器 C++
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
7 0
|
3天前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
11 0
|
3天前
|
程序员 C语言
C语言内存管理:malloc、calloc、realloc与free函数详解
C语言内存管理:malloc、calloc、realloc与free函数详解
6 0
|
5天前
|
缓存 C++
详细解读C++常用库函数C函数库cstdio
详细解读C++常用库函数C函数库cstdio
|
5天前
详细解读C++char类型函数
详细解读C++char类型函数
10 0
|
5天前
|
C++
C++函数对象(仿函数)
C++函数对象(仿函数)
7 0
|
5天前
|
C++
C++函数的默认参数、占位符、重载
C++函数的默认参数、占位符、重载
14 0
|
5天前
|
程序员 编译器 C++
C++内存分区模型(代码区、全局区、栈区、堆区)
C++内存分区模型(代码区、全局区、栈区、堆区)
7 0
|
5天前
|
C++
C++函数
C++函数
5 0