在有些情况下,使用shared_ptr管理某些特别的类型时,这些特别的类型对象的释放不是简单地使用delete关键字释放就可以完成的,需要对shared_ptr进行自定义以完成特殊的清理工作。
shared_ptr所管理的资源的清理工作都是由删除器(deleter)来完成的。shared_ptr提供了一些特殊的构造函数,这些构造函数可以指定shared_ptr删除器,从而对shared_ptr的清理工作进行自定义。
template< class Other, class D > shared_ptr(Other * ptr, D dtor );
这个构造函数带有两个参数。
第一个参数表示:shared_ptr将要获得所有权的某个资源;
第二个参数表示:shared_ptr被销毁时负责释放资源的一个对象,它称之为删除器。当shared_ptr的引用计数变为0时被调用,被保存的资源将以dtor(ptr)的形式传给删除器;
当清理一个文件对象时,往往不是使用delete操作符释放对象,而是使用相应的成员函数关闭文件。
// 2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <time.h>
using namespace std;
class FileCloser
{
public:
//重载“()”操作符
void operator () (FILE* pFile)
{
if ( NULL != pFile )
{
fprintf( pFile, "日志文件结束\n" );
cout<<"关闭日志文件"<<endl;
fclose(pFile);
}
}
};
//向日志文件打印系统时间
void PrintTime( shared_ptr<FILE> spLog )
{
char tmpbuf[128];
_strtime_s( tmpbuf, 128);
fprintf( spLog.get(), "当前系统时间:\t\t%s\n", tmpbuf);
}
//向日志文件打印系统日期
void PrintDate( shared_ptr<FILE> spLog )
{
char tmpbuf[128];
_strdate_s( tmpbuf, 128 );
fprintf( spLog.get(), "当前系统日期为:\t\t%s\n", tmpbuf );
}
int _tmain(int argc, _TCHAR* argv[])
{
FILE* fLog = NULL;
int err = fopen_s(&fLog, "C:\\Users\\sony\\Desktop\\practice\\log.txt", "w");
if ( 0 == err )
{
cout<<"打开日志文件并写入日志"<<endl;
shared_ptr<FILE> spLog( fLog, FileCloser());
fprintf( spLog.get(), "日志文件开始\n" );
PrintTime(spLog);
PrintDate(spLog);
}
//当通过shared_ptr访问资源时,需要对shared_ptr使用&或者get()函数来获得它所管理的指针
return 0;
}
注意的是如果在释放资源时,只需要调用一个单参数函数,可以直接传递给shared_ptr的构造函数这个删除函数的指针即可。
如:
shared_ptr<FILE> spLog( fLog, &fclose );
一样能实现。