或許大家很早就對函數多個出口時的釋放語句或解鎖語句感到萬分無奈而頭痛不已,但是這種情況從此將不再讓你煩惱!因為你有了 —— 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:// membersDWORDm_dwLastError;BOOLm_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:// membersHANDLEm_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_HANDLEm_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&);};