您的位置:首页 > 编程语言 > C语言/C++

C++ : 应用 RAII 技术在 Windows 下实现自动释放锁

2008-01-29 16:15 686 查看
或许大家很早就对函数多个出口时的释放语句或解锁语句感到万分无奈而头痛不已,但是这种情况从此将不再让你烦恼!因为你有了 —— RAII 技术!!
RAIIResource 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&);};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: