ScopeGuard的有个比较能用的上的地方就是,如果需要退出时执行某个操作,可以和方便的使用,而不需要用try finally。不管里面是否抛出异常,都会执行到我们必须执行的函数
实现也是利用了构造和析构函数,在构造函数中,将需要调用的函数地址传入,在析构时调用
class ScopeGuardImplBase
{
/// Copy-assignment operator is not implemented and private.
ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
protected:
~ScopeGuardImplBase()
{}
/// Copy-constructor takes over responsibility from other ScopeGuard.
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;
}
};
没有参数的函数指针的实现
template <typename F>
class ScopeGuardImpl0 : public ScopeGuardImplBase
{
public:
static ScopeGuardImpl0<F> MakeGuard(F fun)
{
return ScopeGuardImpl0<F>(fun);
}
~ScopeGuardImpl0() throw()
{
SafeExecute(*this);
}
void Execute()
{
fun_();
}
protected:
ScopeGuardImpl0(F fun) : fun_(fun)
{}
F fun_;
};
也可以出一个全局的工厂构造
template <typename F>
inline ScopeGuardImpl0<F> MakeGuard(F fun)
{
return ScopeGuardImpl0<F>::MakeGuard(fun);
}
多个参数,成员函数都可以类似扩展实现
使用,函数退出时候肯定会执行HasNone()函数了
void DoStandaloneFunctionTests()
{
::Loki::ScopeGuard guard0 = ::Loki::MakeGuard( &HasNone );
}
另外不想执行的话可以通过guard0.Dismiss();放弃