代理模式:為其他對象提供一種代理以控制對這個對象的訪問。
Proxy:
保存一個引用使得代理可以訪問實體。若RealSubject和Subject的接口相同,Proxy會引用Subject,就相當於在代理類中保存一個Subject指針,該指針會指向RealSubject;
提供一個與Subject的接口相同的接口,這樣代理就可以用來替代實體;
控制對實體的存取,並可能負責創建和刪除它;
其它功能依賴於代理的類型,例如:
遠程代理負責對請求及其參數進行編碼,並向不同地址空間中的實體發送已編碼的請求;
虛代理可以緩存實體的附加信息,以便延遲對它的訪問;
保護代理檢查調用者是否具有實現一個請求所必須的訪問權限。
Subject:定義RealSubject和Proxy的共用接口,這樣就在任何使用RealSubject的地方都可以使用Proxy;
RealSubject:定義Proxy所代理的實體。
1、遠程代理為一個對象在不同的地址空間提供局部代理;
2、虛代理根據需求創建開銷很大的對象;
3、保護代理控制原始對象的訪問;保護代理用於對象應該有不同的訪問權限的時候;
4、智能引用取代了簡單的指針,它在訪問對象時執行一些附加操作,它的典型用途包括:
對指向實際對象的引用計數,這樣當該對象沒有引用時,可以自動釋放它;
引用計數智能指針:
#include#include using namespace std; #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } class KRefCount { public: KRefCount():m_nCount(0){} public: unsigned AddRef(){ return InterlockedIncrement(&m_nCount); } unsigned Release(){ return InterlockedDecrement(&m_nCount); } void Reset(){ m_nCount = 0; } private: unsigned long m_nCount; }; template class SmartPtr { public: SmartPtr(void) : m_pData(NULL) { m_pReference = new KRefCount(); m_pReference->AddRef(); } SmartPtr(T* pValue) : m_pData(pValue) { m_pReference = new KRefCount(); m_pReference->AddRef(); } SmartPtr(const SmartPtr & sp) : m_pData(sp.m_pData) , m_pReference(sp.m_pReference) { m_pReference->AddRef(); } ~SmartPtr(void) { if (m_pReference && m_pReference->Release() == 0) { SAFE_DELETE(m_pData); SAFE_DELETE(m_pReference); } } inline T& operator*() { return *m_pData; } inline T* operator->() { return m_pData; } SmartPtr & operator=(const SmartPtr & sp) { if (this != &sp) { if (m_pReference && m_pReference->Release() == 0) { SAFE_DELETE(m_pData); SAFE_DELETE(m_pReference); } m_pData = sp.m_pData; m_pReference = sp.m_pReference; m_pReference->AddRef(); } return *this; } SmartPtr & operator=(T* pValue) { if (m_pReference && m_pReference->Release() == 0) { SAFE_DELETE(m_pData); SAFE_DELETE(m_pReference); } m_pData = pValue; m_pReference = new KRefCount; m_pReference->AddRef(); return *this; } T* Get() { T* ptr = NULL; ptr = m_pData; return ptr; } void Attach(T* pObject) { if (m_pReference->Release() == 0) { SAFE_DELETE(m_pData); SAFE_DELETE(m_pReference); } m_pData = pObject; m_pReference = new KRefCount; m_pReference->AddRef(); } T* Detach() { T* ptr = NULL; if (m_pData) { ptr = m_pData; m_pData = NULL; m_pReference->Reset(); } return ptr; } private: KRefCount* m_pReference; T* m_pData; }; class CTest { public: CTest(int b) : a(b) {} private: int a; }; int main() { SmartPtr pSmartPtr1(new CTest(10)); SmartPtr pSmartPtr2(new CTest(20)); pSmartPtr1 = pSmartPtr2; }