C++ : 应用 RAII 技术在 Windows 下实现自动释放锁
2008-01-29 16:15
686 查看
或许大家很早就对函数多个出口时的释放语句或解锁语句感到万分无奈而头痛不已,但是这种情况从此将不再让你烦恼!因为你有了 —— RAII 技术!!
RAII(Resource Acquisition Is Initialization 资源获得即初始化)是管理资源的一种方式,它在构造对象时初始化资源,析构对象时释放资源,有时也把这2个过程分为RAII和RRID(Resource Release Is Destruction 资源释放即析构)
以下是以 CRITICAL_SECTION 实现的非 MFC 版本,相信据此实现 MFC 的 CCriticalSection 版本对大家都是举手之事。
////////////////////////////////////////////////////////////////////////#pragma onceclass CTLock {public:// note: the parameter cs must be initialized ( InitializeCriticalSection(&cs); )CTLock(CRITICAL_SECTION& cs):m_cs(cs), bLeaved(FALSE){EnterCriticalSection(&m_cs);}// sometimes we need release it as soon as possible, so just call Leave().void Leave(){if (!bLeaved){LeaveCriticalSection(&m_cs);bLeaved = TRUE;}}// auto-releasevirtual ~CTLock(){if (!bLeaved){LeaveCriticalSection(&m_cs);}}protected:// membersCRITICAL_SECTION& m_cs;BOOL bLeaved;private:// no copy or assignmentCTLock(const CTLock&);CTLock& operator=(const CTLock&);};#ifdef AFX_DATA#include <afxmt.h>class CKSLock {public:CKSLock(CCriticalSection& cs):m_cs(cs), bLeaved(FALSE){m_cs.Lock();}// sometimes we need release it as soon as possible, so just call Leave().void Leave(){if (!bLeaved){m_cs.Unlock();bLeaved = TRUE;}}// auto-releasevirtual ~CKSLock(){if (!bLeaved){m_cs.Unlock();}}protected:// membersCCriticalSection& m_cs;BOOL bLeaved;private:// no copy or assignmentCKSLock(const CKSLock&);CKSLock& operator=(const CKSLock&);};#endifclass CReserveLastErr{public:CReserveLastErr():m_bRelease(FALSE){m_dwLastError = GetLastError();}// auto-releasevirtual ~CReserveLastErr(){if (!m_bRelease){SetLastError(m_dwLastError);}}void Pop(){if (!m_bRelease){SetLastError(m_dwLastError);}}void Cancel(){m_bRelease = TRUE;}protected:// membersDWORD m_dwLastError;BOOL m_bRelease;private:// no copy or assignmentCReserveLastErr(const CReserveLastErr&);CReserveLastErr& operator=(const CReserveLastErr&);};//// //class CAutoCloseHandle{public:CAutoCloseHandle(HANDLE handle):m_hHandle(handle){}// auto-releasevirtual ~CAutoCloseHandle(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (INVALID_HANDLE_VALUE != m_hHandle){bRet = CloseHandle(m_hHandle);m_hHandle = INVALID_HANDLE_VALUE;}return bRet;}protected:// membersHANDLE m_hHandle;private:// no copy or assignmentCAutoCloseHandle(const CAutoCloseHandle&);CAutoCloseHandle& operator=(const CAutoCloseHandle&);};//// //class CAutoCloseHKEY{public:CAutoCloseHKEY(HKEY hKey):m_hKey(hKey){}// auto-releasevirtual ~CAutoCloseHKEY(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (NULL != m_hKey){bRet = (ERROR_SUCCESS == ::RegCloseKey(m_hKey));m_hKey = NULL;}return bRet;}protected:// membersHKEY m_hKey;private:// no copy or assignmentCAutoCloseHKEY(const CAutoCloseHKEY&);CAutoCloseHKEY& operator=(const CAutoCloseHKEY&);};#include <winsvc.h>//// //class CAutoCloseServiceHandle{public:CAutoCloseServiceHandle(SC_HANDLE handle):m_hHandle(handle){}// auto-releasevirtual ~CAutoCloseServiceHandle(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (NULL != m_hHandle){bRet = CloseServiceHandle(m_hHandle);m_hHandle = NULL;}return bRet;}protected:// membersSC_HANDLE m_hHandle;private:// no copy or assignmentCAutoCloseServiceHandle(const CAutoCloseServiceHandle&);CAutoCloseServiceHandle& operator=(const CAutoCloseServiceHandle&);};//// //class CAutoReleaseChar{public:CAutoReleaseChar(char* pBuf):m_pBuf(pBuf){}// auto-releasevirtual ~CAutoReleaseChar(){Release();}// releasevoid Release(){if (NULL != m_pBuf){delete[] m_pBuf;m_pBuf = NULL;}}protected:// memberschar* m_pBuf;private:// no copy or assignmentCAutoReleaseChar(const CAutoReleaseChar&);CAutoReleaseChar& operator=(const CAutoReleaseChar&);};
RAII(Resource Acquisition Is Initialization 资源获得即初始化)是管理资源的一种方式,它在构造对象时初始化资源,析构对象时释放资源,有时也把这2个过程分为RAII和RRID(Resource Release Is Destruction 资源释放即析构)
以下是以 CRITICAL_SECTION 实现的非 MFC 版本,相信据此实现 MFC 的 CCriticalSection 版本对大家都是举手之事。
////////////////////////////////////////////////////////////////////////#pragma onceclass CTLock {public:// note: the parameter cs must be initialized ( InitializeCriticalSection(&cs); )CTLock(CRITICAL_SECTION& cs):m_cs(cs), bLeaved(FALSE){EnterCriticalSection(&m_cs);}// sometimes we need release it as soon as possible, so just call Leave().void Leave(){if (!bLeaved){LeaveCriticalSection(&m_cs);bLeaved = TRUE;}}// auto-releasevirtual ~CTLock(){if (!bLeaved){LeaveCriticalSection(&m_cs);}}protected:// membersCRITICAL_SECTION& m_cs;BOOL bLeaved;private:// no copy or assignmentCTLock(const CTLock&);CTLock& operator=(const CTLock&);};#ifdef AFX_DATA#include <afxmt.h>class CKSLock {public:CKSLock(CCriticalSection& cs):m_cs(cs), bLeaved(FALSE){m_cs.Lock();}// sometimes we need release it as soon as possible, so just call Leave().void Leave(){if (!bLeaved){m_cs.Unlock();bLeaved = TRUE;}}// auto-releasevirtual ~CKSLock(){if (!bLeaved){m_cs.Unlock();}}protected:// membersCCriticalSection& m_cs;BOOL bLeaved;private:// no copy or assignmentCKSLock(const CKSLock&);CKSLock& operator=(const CKSLock&);};#endifclass CReserveLastErr{public:CReserveLastErr():m_bRelease(FALSE){m_dwLastError = GetLastError();}// auto-releasevirtual ~CReserveLastErr(){if (!m_bRelease){SetLastError(m_dwLastError);}}void Pop(){if (!m_bRelease){SetLastError(m_dwLastError);}}void Cancel(){m_bRelease = TRUE;}protected:// membersDWORD m_dwLastError;BOOL m_bRelease;private:// no copy or assignmentCReserveLastErr(const CReserveLastErr&);CReserveLastErr& operator=(const CReserveLastErr&);};//// //class CAutoCloseHandle{public:CAutoCloseHandle(HANDLE handle):m_hHandle(handle){}// auto-releasevirtual ~CAutoCloseHandle(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (INVALID_HANDLE_VALUE != m_hHandle){bRet = CloseHandle(m_hHandle);m_hHandle = INVALID_HANDLE_VALUE;}return bRet;}protected:// membersHANDLE m_hHandle;private:// no copy or assignmentCAutoCloseHandle(const CAutoCloseHandle&);CAutoCloseHandle& operator=(const CAutoCloseHandle&);};//// //class CAutoCloseHKEY{public:CAutoCloseHKEY(HKEY hKey):m_hKey(hKey){}// auto-releasevirtual ~CAutoCloseHKEY(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (NULL != m_hKey){bRet = (ERROR_SUCCESS == ::RegCloseKey(m_hKey));m_hKey = NULL;}return bRet;}protected:// membersHKEY m_hKey;private:// no copy or assignmentCAutoCloseHKEY(const CAutoCloseHKEY&);CAutoCloseHKEY& operator=(const CAutoCloseHKEY&);};#include <winsvc.h>//// //class CAutoCloseServiceHandle{public:CAutoCloseServiceHandle(SC_HANDLE handle):m_hHandle(handle){}// auto-releasevirtual ~CAutoCloseServiceHandle(){Close();}// releaseBOOL Close(){BOOL bRet = TRUE;if (NULL != m_hHandle){bRet = CloseServiceHandle(m_hHandle);m_hHandle = NULL;}return bRet;}protected:// membersSC_HANDLE m_hHandle;private:// no copy or assignmentCAutoCloseServiceHandle(const CAutoCloseServiceHandle&);CAutoCloseServiceHandle& operator=(const CAutoCloseServiceHandle&);};//// //class CAutoReleaseChar{public:CAutoReleaseChar(char* pBuf):m_pBuf(pBuf){}// auto-releasevirtual ~CAutoReleaseChar(){Release();}// releasevoid Release(){if (NULL != m_pBuf){delete[] m_pBuf;m_pBuf = NULL;}}protected:// memberschar* m_pBuf;private:// no copy or assignmentCAutoReleaseChar(const CAutoReleaseChar&);CAutoReleaseChar& operator=(const CAutoReleaseChar&);};
相关文章推荐
- 一种在windows平台下实现自动操作应用的方法,附带源码地址及使用方法
- Windows中多指针输入技术的实现与应用(10 双鼠标五子棋源代码 全系列完)
- 单例模式——C++实现自动释放单例类的实例
- [转]单例模式——C++实现自动释放单例类的实例
- C++在Windows环境下多线程自动锁的实现
- 利用C++ RAII技术自动回收堆内存
- 单例模式——C++实现自动释放单例类的实例
- Windows下C++实现线程池功能(固定线程数,自动调整未实现)(
- windows下运用批处理实现一键自动开启多个应用
- [转]单例模式——C++实现自动释放单例类的实例
- 单例模式——C++实现自动释放单例类的实例
- 通过RAII机制实现资源的自动释放
- [转]单例模式——C++实现自动释放单例类的实例
- 单例模式——C++实现自动释放单例类的实例
- Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
- 深度剖析C++对象池自动回收技术实现
- Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
- Windows平台下C++插件系统实现的几个关键技术问题及其解决思路
- Windows中多指针输入技术的实现与应用(4多鼠标输入的底层实现)
- C++ 动态分配资源的自动释放 – auto_ptr的实现原理