代理模式:为其它对象提供一种代理以控制对这个对象的訪问。
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代理实际的数据,去实现了指针的行为。加入了引用计数,从而实现了智能指针。