ScopeGuard 主要分两种情况:
1. 调用非成员函数
2. 调用成员函数
含一个参数,非成员函数 的 ScopeGuard 模板:
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
namespace YHL {
// 完全负责管理 dismiss 标志
class ScopeGuard_Base {
private:
// 禁止复制和赋值
ScopeGuard_Base& operator=(const ScopeGuard_Base&) = delete ;
public:
ScopeGuard_Base() throw()
: dismissed(false) {}
// 更改 “撤销” 标志 ...const throw() ?
void Dismiss(const bool _dismissed) const throw() {
dismissed = _dismissed ;
}
protected:
mutable bool dismissed ;
~ScopeGuard_Base() = default ;
// 转移 dismissed 所有权
ScopeGuard_Base(const ScopeGuard_Base& other) throw()
: dismissed(other.dismissed) {
other.Dismiss(true) ;
}
// 执行安全操作, 将 dismissed 完全控制在 ScopeGuard_Base 中
template<typename T>
static void safeExecute(T &someOne) throw() {
if ( someOne.dismissed == false )
try {
someOne.Execute() ;
} catch (...) {}
}
} ;
// 基类引用保存子类对象, 延长临时对象生命期
typedef const ScopeGuard_Base& ScopeGuard ;
/* 含有一个参数的 ScopeGuard,
* 1. 负责生成 ScopeGuard
* 2. 负责管理 执行函数function 和 对象 object */
template<typename Fun, typename Obj>
class ScopeGuard_1 : public ScopeGuard_Base {
protected:
Fun function ;
const Obj object ;
ScopeGuard_1(Fun fun, Obj obj) : function(fun), object(obj)
{}
public:
// 因为 dismissed 完全交给基类
~ScopeGuard_1() throw() { safeExecute(*this) ; }
// 真正的执行在 Execute, 因为函数模板在子类
void Execute() {
cout << "执行清理工作\n" ;
function(object) ;
}
// 向外提供生成 ScopeGuard 的接口
static ScopeGuard_1<Fun, Obj> makeGuard(Fun fun, Obj obj) {
return ScopeGuard_1<Fun, Obj>(fun, obj) ;
}
} ;
// 构造一个参数的 ScopeGuard
template<typename Fun, typename Obj>
inline ScopeGuard_1<Fun, Obj> makeGuard(Fun fun, Obj obj) {
return ScopeGuard_1<Fun, Obj>::makeGuard(fun, obj) ;
}
}
int main () {
using namespace YHL ;
if ( void *ptr = std::malloc(1024) )
ScopeGuard someOne = makeGuard(std::free, ptr) ;
FILE *handle = fopen("RAII(5).txt", "w+") ;
ScopeGuard outRAII = makeGuard(std::fclose, handle) ;
return 0 ;
}
含 0 个参数,成员函数 的ScopeGuard 模板
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
namespace YHL {
// 完全负责管理 dismiss 标志
class ScopeGuard_Base {
private:
// 禁止复制和赋值
ScopeGuard_Base& operator=(const ScopeGuard_Base&) = delete ;
public:
ScopeGuard_Base() throw()
: dismissed(false) {}
// 更改 “撤销” 标志 ...const throw() ?
void Dismiss(const bool _dismissed) const throw() {
dismissed = _dismissed ;
}
protected:
mutable bool dismissed ;
~ScopeGuard_Base() = default ;
// 转移 dismissed 所有权
ScopeGuard_Base(const ScopeGuard_Base& other) throw()
: dismissed(other.dismissed) {
other.Dismiss(true) ;
}
// 执行安全操作, 将 dismissed 完全控制在 ScopeGuard_Base 中
template<typename T>
static void safeExecute(T &someOne) throw() {
if ( someOne.dismissed == false )
try {
someOne.Execute() ;
} catch (...) {}
}
} ;
typedef const ScopeGuard_Base& ScopeGuard ;
/* 含有 0 个参数的 ScopeGuard,
* 1. 负责生成 ScopeGuard
* 2. 负责管理 对象 object 及其成员函数 function */
template<typename Fun, typename Obj>
class ScopeGuard_Member_0 : public ScopeGuard_Base {
protected:
Fun function ;
Obj &object ;
ScopeGuard_Member_0(Fun fun, Obj& obj) : function(fun), object(obj)
{}
public:
~ScopeGuard_Member_0() throw() {
safeExecute(*this) ;
}
void Execute() {
cout << "执行清理工作\n" ;
// 调用方式 .*
(object.*function)() ;
}
// 向外提供生成 ScopeGuard 的接口
static ScopeGuard_Member_0<Fun, Obj> makeGuard(Fun fun, Obj &obj) {
return ScopeGuard_Member_0<Fun, Obj>(fun, obj) ;
}
} ;
// 构造一个参数的 ScopeGuard
template<typename Fun, typename Obj>
inline ScopeGuard_Member_0<Fun, Obj> makeGuard(Fun fun, Obj &obj) {
return ScopeGuard_Member_0<Fun, Obj>::makeGuard(fun, obj) ;
}
}
int main () {
using namespace YHL ;
std::ofstream out("RAII(5).txt") ;
out << "In the rest of my life\n" ;
ScopeGuard outRAII = makeGuard(std::ofstream::close, out) ;
std::vector<int> example ;
rep ( i , 0 , 10 )
example.emplace_back(i + 1) ;
if ( true ) {
ScopeGuard VecRAII = makeGuard(std::vector<int>::pop_back, example) ;
cout << "pop_back 一次\n" ;
}
for ( const auto &it : example )
cout << it << " " ;
cout << endl ;
return 0 ;
}
含一个参数,成员函数的 ScopeGuard 模板:(其余类推)
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
namespace YHL {
// 完全负责管理 dismiss 标志
class ScopeGuard_Base {
private:
// 禁止复制和赋值
ScopeGuard_Base& operator=(const ScopeGuard_Base&) = delete ;
public:
ScopeGuard_Base() throw()
: dismissed(false) {}
// 更改 “撤销” 标志 ...const throw() ?
void Dismiss(const bool _dismissed) const throw() {
dismissed = _dismissed ;
}
protected:
mutable bool dismissed ;
~ScopeGuard_Base() = default ;
// 转移 dismissed 所有权
ScopeGuard_Base(const ScopeGuard_Base& other) throw()
: dismissed(other.dismissed) {
other.Dismiss(true) ;
}
// 执行安全操作, 将 dismissed 完全控制在 ScopeGuard_Base 中
template<typename T>
static void safeExecute(T &someOne) throw() {
if ( someOne.dismissed == false )
try {
someOne.Execute() ;
} catch (...) {}
}
} ;
typedef const ScopeGuard_Base& ScopeGuard ;
/* 含有 0 个参数的 ScopeGuard,
* 1. 负责生成 ScopeGuard
* 2. 负责管理 对象 object 及其成员函数 function */
template<typename Fun, typename Obj, typename Para>
class ScopeGuard_Member_1 : public ScopeGuard_Base {
protected:
Fun function ;
Obj &object ;
Para parameter ;
ScopeGuard_Member_1(Fun fun, Obj& obj, Para para)
: function(fun), object(obj), parameter(para)
{}
public:
~ScopeGuard_Member_1() throw() {
safeExecute(*this) ;
}
void Execute() {
cout << "执行清理工作\n" ;
(object.*function)(parameter) ;
}
// 向外提供生成 ScopeGuard 的接口
static ScopeGuard_Member_1<Fun, Obj, Para> makeGuard(Fun fun, Obj &obj, Para para) {
return ScopeGuard_Member_1<Fun, Obj, Para>(fun, obj, para) ;
}
} ;
// 构造一个参数的 ScopeGuard
template<typename Fun, typename Obj, typename Para>
inline ScopeGuard_Member_1<Fun, Obj, Para> makeGuard(Fun fun, Obj &obj, Para para) {
return ScopeGuard_Member_1<Fun, Obj, Para>::makeGuard(fun, obj, para) ;
}
}
int main () {
using namespace YHL ;
class Entity {
private:
int data ;
public:
Entity() : data(1022) {}
int get() const { return data ; }
void reset(const int other) {
data = other ;
}
} ;
Entity example ;
if ( true )
ScopeGuard reset = makeGuard(Entity::reset, example, 0) ;
cout << "data : " << example.get() << endl ;
return 0 ;
}