標籤:
代理模式:為其他對象提供一種代理以控制對這個對象的訪問。
Proxy:
儲存一個引用使得代理可以訪問實體。若RealSubject和Subject的介面相同,Proxy會引用Subject,就相當於在代理類中儲存一個Subject指標,該指標會指向RealSubject;
提供一個與Subject的介面相同的介面,這樣代理就可以用來替代實體;
控制對實體的存取,並可能負責建立和刪除它;
其它功能依賴於代理的類型,例如:
遠程代理負責對請求及其參數進行編碼,並向不同地址空間中的實體發送已編碼的請求;
虛代理可以緩衝實體的附加資訊,以便延遲對它的訪問;
保護代理檢查調用者是否具有實現一個請求所必須的存取權限。
Subject:定義RealSubject和Proxy的共用介面,這樣就在任何使用RealSubject的地方都可以使用Proxy;
RealSubject:定義Proxy所代理的實體。
1、遠程代理為一個對象在不同的地址空間提供局部代理;
2、虛代理根據需求建立開銷很大的對象;
3、保護代理控制原始對象的訪問;保護代理用於對象應該有不同的存取權限的時候;
4、智能引用取代了簡單的指標,它在訪問對象時執行一些附加操作,它的典型用途包括:
對指向實際對象的引用計數,這樣當該對象沒有引用時,可以自動釋放它;
引用計數智能指標:
#include <iostream>#include <windows.h>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 <typename T>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<T>& 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<T>& operator=(const SmartPtr<T>& 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<T>& 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<CTest> pSmartPtr1(new CTest(10));SmartPtr<CTest> pSmartPtr2(new CTest(20));pSmartPtr1 = pSmartPtr2;}
智能指標使用引用計數實現時,就是最好的使用代理模式的例子。在上面的例子中,SmartPtr就是一個代理類,而T* m_pData才是實際的資料。SmartPtr代理實際的資料,去實現了指標的行為,添加了引用計數,從而實現了智能指標。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
[C++設計模式] proxy 代理模式