背景:
在平时写代码时,经常需要对不为nullptr的指针进行释放且置空的操作,如下:
if(m_pObj != nullptr)
{
delete m_pObj;
m_pObj = nullptr;
}
可以发现,对于这种简单地释放指针的操作,需要5行代码去完成。如果某个类中具有多个成员指针,在析构函数中就得写很多行的代码去完成各个指针的释放。
优化操作
对于上面提出的问题,做了下面的封装。
/******************************************************************************
Include files头文件
******************************************************************************/
#include <functional>
/******************************************************************************
回调函数定义
******************************************************************************/
/*!
* \brief 析构前执行
*/
using BeforeReleaseExecFun = std::function<void(void)>;
/******************************************************************************
函数定义
******************************************************************************/
/*!
* \brief 释放指针
* \param ptr 待释放的指针
* \param func 待执行的回调
*/
template<typename T>
void DeletePtr(T*& ptr, BeforeReleaseExecFun func = nullptr)
{
if(ptr != nullptr)
{
if(func != nullptr)
{
func();
}
delete ptr;
ptr = nullptr;
}
}
上面的DeletePtr函数接口,有两个形参,
(1)T*& ptr:传入待释放的指针;
(2)BeforeReleaseExecFun func:在释放指针前,需要执行的一个操作,可以传入一个无参的函数或一个无参的Lambda表达式。比如释放通信指针时,可能需要进行Close或者Disconnect操作。如果无需求,则无需赋值第二个参数。
使用示例
/*!
* \brief tcp类
*/
class Tcp
{
public:
/*!
* \brief 构造函数
*/
Tcp()
{
cout << "New Tcp" << endl;
}
/*!
* \brief 析构函数
*/
~Tcp()
{
cout << "Delete Tcp" << endl;
}
/*!
* \brief 关闭连接
*/
void Close()
{
cout << "Tcp Close" << endl;
}
};
/*!
* \brief 通信类
*/
class CommunicationModule
{
public:
/*!
* \brief 构造函数
*/
CommunicationModule()
{
m_pTcp = new Tcp;
}
/*!
* \brief 析构函数
*/
~CommunicationModule()
{
// 此处对m_pTcp进行释放,并且在释放指针前进行Close操作
DeletePtr(m_pTcp, [=]() { m_pTcp->Close(); });
// 若无需进行Close操作,则直接如下操作
// DeletePtr(m_pTcp);
}
private:
/*!
* \brief tcp对象
*/
Tcp* m_pTcp = nullptr;
};
上述中,对指针释放的操作进行了简单地封装,并且写了一个简单的示例,在对指针进行释放时,由最初的5行代码,可以精简为1行,如此,则会达到进一步简化代码和简化操作的效果。