[C ++ design mode] proxy Mode
Proxy mode: provides a proxy for other objects to control access to this object.
Proxy:
Save a reference so that the proxy can access the object. If the interfaces of RealSubject and Subject are the same, the Proxy will reference Subject, which is equivalent to saving a Subject pointer in the Proxy class, which will point to RealSubject;
Provides the same interface as the Subject interface, so that the proxy can be used to replace the object;
Controls the access to an object and may be responsible for creating and deleting it;
Other functions depend on the proxy type, for example:
The remote proxy is responsible for encoding requests and their parameters, and sending encoded requests to entities in different address spaces;
Virtual proxy can cache additional information of an object to delay its access;
The protection proxy checks whether the caller has the required access permissions to implement a request.
Subject: defines the common interfaces of RealSubject and Proxy, so that Proxy can be used wherever RealSubject is used;
RealSubject: defines the entity Proxy.
1. remote proxy provides local proxy for an object in different address spaces;
2. Virtual proxy creates objects with high overhead as needed;
3. Protect the proxy to control access to the original object; and protect the proxy when the object should have different access permissions;
4. Intelligent reference replaces simple pointers. It performs some additional operations when accessing objects. Its typical uses include:
The reference count pointing to the actual object. When this object is not referenced, it can be automatically released;
Reference count smart pointer:
#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;}
When smart pointers are implemented using reference counting, it is the best example of using the proxy mode. In the above example, SmartPtr is a proxy class, and T * m_pData is the actual data. The actual data of the SmartPtr proxy is used to implement pointer behavior, and the reference count is added to implement smart pointers.