zoukankan      html  css  js  c++  java
  • [C++设计模式] proxy 代理模式

    代理模式:为其它对象提供一种代理以控制对这个对象的訪问。


    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代理实际的数据,去实现了指针的行为。加入了引用计数,从而实现了智能指针。

  • 相关阅读:
    Mac下搭建php开发环境
    phalcon:跟踪sql语句
    phalcon的CLI应用
    phalcon遇到的那些坑
    浏览器 批量大文件上传下载
    网页 批量大文件上传下载
    B/S 批量大文件上传下载
    JavaScript 批量大文件上传下载
    js 批量大文件上传下载
    vue 批量大文件上传下载
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6821972.html
Copyright © 2011-2022 走看看