设计模式之2---代理模式

打算去泰国旅行,可是办签证太麻烦啦,得自己去大使馆办理,可是自己又要工作,又不喜欢去搞这样的流程。怎么办呢?还好淘宝上有不少商家,可以代理你去办理,省去了不少的麻烦。只需要把你要办理的相关资料跟代理统一就行啦。

实际上签证代办,就是我们生活中使用到的代理模式。

什么是代理?抽象的讲就是:为其他对象提供一种代理以控制这这个对象的访问。

UML图


proxy: 保存一个realsubject的对象,并且提供与subject相同的接口对用户;提供删除和创建realsubject的功能;

subject: 定义realsubject和proxy的共用接口;

realsubject:proxy代理的实体;


代理模式的经典应用场景,便是c++的智能指针,c++指针容易导致内存泄漏,缺少垃圾回收一直为人诟病。

用只能指针(proxy)来实现指针(subject)的创建和删除,增加引用计数器提供智能回收。

#include <stdio.h>
#include <stdint.h>
#include <pthread.h>

#define SAFEDEL(p) if (p) {delete p;} p = NULL;

class prefCounter {
public:
  prefCounter() {
    m_ref = 0;
  }
  
  uint32_t add_ref() {
    pthread_mutex_lock(&m_ref_addlock);
    
    do {
      if (m_ref == 0xffffffff) {
        break;
      }
      m_ref++;
    } while (0);
    
    pthread_mutex_unlock(&m_ref_addlock);
    return m_ref;
  }
  
  uint32_t dec_ref() {
    pthread_mutex_lock(&m_ref_declock);
    
    do {
      if (m_ref == 0) {
        break;
      }
      m_ref--;
    } while (0);
    
    pthread_mutex_unlock(&m_ref_declock);
    return m_ref;
  }
  
  void reset() {
    m_ref = 0;
  }
  
  uint32_t get_ref() {
    return m_ref;
  }
public:
  uint32_t m_ref;
  pthread_mutex_t m_ref_addlock;
  pthread_mutex_t m_ref_declock;
};

template <class T>
class smartPtr {
  
public:
  
  smartPtr(void)
  : m_ptr(NULL) {
    m_ref = new prefCounter();
    m_ref->add_ref();
  }
  
  smartPtr(T *ptr)
  : m_ptr(ptr) {
    m_ref = new prefCounter();
    m_ref->add_ref();
  }
  
  smartPtr(const smartPtr<T> &sp)
  : m_ptr(sp.m_ptr)
  , m_ref(sp.m_ref) {
    m_ref->add_ref();
  }
  
  ~smartPtr(void) {
    dec_ref();
  }
  
  inline T& operator*() {
    return *m_ptr;
  }
  
  inline T* operator->() {
    return m_ptr;
  }
  
  uint32_t get_ref() {
    return m_ref->get_ref();
  }
  
  smartPtr<T> & operator=(const smartPtr<T> &sp) {
    if (this != &sp) {
        printf("value[%d] operator= called and this is not self\n", *m_ptr);
      dec_ref();
      
      m_ptr = sp.m_ptr;
      m_ref = sp.m_ref;
      m_ref->add_ref();
    }
    return *this;
  }
  
  smartPtr<T> & operator=(T *ptr) {
    if (m_ref && m_ref->dec_ref() == 0) {
      dec_ref();
    }
    m_ptr = ptr;
    m_ref = new prefCounter();
    m_ref->add_ref();
    return *this;
  }
  
  void attach(T *ptr){
    
  }
  
  T * detach() {
    T *ptr = NULL;
    
    if (m_ptr) {
      ptr = m_ptr;
      m_ptr = NULL;
      m_ref->reset();
    }
    return ptr;
  }
  
private:
  void dec_ref(){
    if (m_ref && m_ref->dec_ref() == 0) {
      SAFEDEL(m_ref);
      SAFEDEL(m_ptr);
    }
  }

private:
  T *m_ptr;
  prefCounter *m_ref;
};


上面的例子中smartPtr是一个代理类,而m_ptr才是真正的主体,指针使用的常用接口(*,->)都在smartPtr中提供了相应的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值