利用std::unique_ptr释放资源

        unique_ptr是stl定义的一种智能指针,利用C++的RAII机制进行内存管理,防止内存泄漏。除了内存之外,unique_ptr还可以用来管理其他资源,如FILE,代码如下:

#include <cstdio>
#include <memory>

//文件句柄关闭仿函数
struct FileCloseHandle {
    void operator() (FILE *pf) {
        if (pf != nullptr) {
            fclose(pf);
        }
    }
};

//定义文件句柄管理类型
typedef std::unique_ptr<FILE, FileCloseHandle> FileGuard;

int main(int argc, char **argv)
{
    FileGuard fg(fopen("a.txt", "w"));
    if (fg.get() == nullptr) {
        fprintf(stderr, "failed to open a.txt !\n");
        return 1;
    }
    fprintf(fg.get(), "hello world !\n");

    return 0;
}

         FileCloseHandle是一个仿函数,用于释放文件句柄;FileGuard使用unique_ptr定义了文件句柄自动释放的类型。FileGuard为什么能够实现文件句柄的自动释放?可以看下unique_ptr的定义。

template <class _Tp, class _Dp = default_delete<_Tp> >
class unique_ptr {
    ......
};

        通过unique_ptr的定义(如下),其模板参数有两个 :_Tp为对象的类型;_Dp为对象的释放方法。在unique_ptr对象生命周期结束时,通过调用_Dp释放资源。默认的释放方法为default_delete,是一个仿函数,其通过delete释放指针。定义如下(非全部代码):

//用于释放单个指针
template <class _Tp>
struct default_delete {
    template <class _Up>
    default_delete(const default_delete<_Up>&,
                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
                     0) _NOEXCEPT {}

    void operator()(_Tp* __ptr) const _NOEXCEPT {
        delete __ptr;
    }
};

//用于释放数组指针
template <class _Tp>
struct default_delete<_Tp[]> {
private:
    template <class _Up>
    struct _EnableIfConvertible
      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};

public:
    template <class _Up>
    default_delete(const default_delete<_Up[]>&,
                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}

    template <class _Up>
    typename _EnableIfConvertible<_Up>::type
    operator()(_Up* __ptr) const _NOEXCEPT {
        delete[] __ptr;
    }
};

        通过default_delete的定义,可以看出: 

        1.定义一个释放仿函数类型,必须实现operator()(T *ptr)

        2.使用malloc申请的内存,必须使用自定义释放函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值