程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> [C++設計模式] proxy 代理模式

[C++設計模式] proxy 代理模式

編輯:關於C++

代理模式:為其他對象提供一種代理以控制對這個對象的訪問。

\

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;
}

智能指針使用引用計數實現時,就是最好的使用代理模式的例子。在上面的例子中,SmartPtr就是一個代理類,而T* m_pData才是實際的數據。SmartPtr代理實際的數據,去實現了指針的行為,添加了引用計數,從而實現了智能指針。

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved