Loki 库学习(1)ScopeGuard

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 ;
}

猜你喜欢

转载自blog.csdn.net/nishisiyuetian/article/details/81623456