RAII的应用在C++这种高危语言中尤其重要,结合模板,效果更爽。
先看应用:
#include "stdafx.h"
using namespace Loki;
void myFree(char* s)
{
if (s != NULL)
{
free(s);
}
printf("myFree(char*) was invoked.\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
{
char* s = (char*)malloc(128);
ScopeGuard sg = MakeGuard(myFree, s);
//sg.Dismiss();
}
system("pause");
return 0;
}
再看模板原理:
namespace Loki
{
class ScopeGuardImplBase
{
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
protected:
~ScopeGuardImplBase()
{}
ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
: dismissed_(other.dismissed_)
{
other.Dismiss();
}
template <typename J>
static void SafeExecute(J& j) throw()
{
if (!j.dismissed_)
try
{
j.Execute();
}
catch(...)
{}
}
mutable bool dismissed_;
public:
ScopeGuardImplBase() throw() : dismissed_(false)
{}
void Dismiss() const throw()
{
dismissed_ = true;
}
};
typedef const ScopeGuardImplBase& ScopeGuard;
template <typename F, typename P1>
class ScopeGuardImpl1 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
{
return ScopeGuardImpl1<F, P1>(fun, p1);
}
~ScopeGuardImpl1() throw()
{
SafeExecute(*this);
}
void Execute()
{
fun_(p1_);
}
protected:
ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
{}
F fun_;
const P1 p1_;
};
template <typename F, typename P1>
inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
{
return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
}
} // namespace Loki