Proxy代理模式——对象结构模式
1.意图
为其他对象提供一种代理以控制对这个对象的访问。
2.适用性
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。
1)远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
2)虚代理(Virtual Proxy)根据需要创建开销很大的对象。
3)保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该用不同的访问权限的时候。
4)智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。它的典型用途包括 :
- 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为Smart Pointers(智能指针))
- 当第一次引用一个持久对象时,将它装入内存
- 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
3.结构
4.参与者
- Proxy
—— 保存一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,Proxy会引用Subject.
—— 提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体
—— 控制对实体的存取,并可能负责创建和删除它
—— 其他功能依赖于代理的类型:
-
Remote Proxy负责对请求及其参数进行编码,并向不同地址空间中的实体发送已编码的请求
-
Virtual Proxy可以缓存实体的附加信息,以便延迟对它的访问。
-
Protection Proxy检查调用者是否具有实现一个请求所必需的访问权限。
- Subject
—— 定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
- RealSubject
—— 定义Proxy所代表的实体
5.案例
#include <iostream>
using namespace std;
template <class T>
class Auto_Ptr;
//智能指针和引用计数
template <class T>
class Ref_Ptr
{
friend class Auto_Ptr<T>;
private:
T* m_pTtr;//实际的指针
size_t m_RefCount;//引用计数
Ref_Ptr(T* p);
virtual ~Ref_Ptr();
};
template<class T>
Ref_Ptr<T>::Ref_Ptr(T* p)
{
m_pTtr = p;
m_RefCount = 1;
cout << "Ref_Ptr()构造函数调用" << endl;
}
template<class T>
Ref_Ptr<T>::~Ref_Ptr()
{
if (m_pTtr)
{
cout << "~Ref_Ptr()析构函数调用" << endl;
delete m_pTtr;
m_pTtr = nullptr;
m_RefCount = 0;
}
m_pTtr = nullptr;
}
//智能指针对象
template<class T>
class Auto_Ptr
{
public:
Auto_Ptr();
Auto_Ptr(T* p);
~Auto_Ptr();
//运算符重载
Auto_Ptr<T>& operator = (Auto_Ptr& other);
T& operator *();
T* operator ->();
//拷贝构造函数
Auto_Ptr(Auto_Ptr<T>& other);
private:
Ref_Ptr<T>* m_pRef;
};
template<class T>
Auto_Ptr<T>::Auto_Ptr() { m_pRef = nullptr; }
template<class T>
Auto_Ptr<T>::Auto_Ptr(T* p)
{
m_pRef = new Ref_Ptr<T>(p);
cout << "Auto_ptr(T* p)构造函数调用" << endl;
}
template<class T>
Auto_Ptr<T>::Auto_Ptr(Auto_Ptr<T>& other)
{
m_pRef = other.m_pRef;
++(m_pRef->m_RefCount);
cout << "Auto_ptr(& other)拷贝构造函数调用" << endl;
}
template<class T>
Auto_Ptr<T>& Auto_Ptr<T>::operator=(Auto_Ptr& other)
{
//将右操作数对应引用+1
++(other.m_pRef->m_RefCount);
//由于左操作数指向了新对象,所以将操作数-1
//防止自赋值
if (m_pRef)
{
if (--(m_pRef->m_RefCount) == 0) { delete m_pRef; }
}
m_pRef = other.m_pRef;
printf("operator = 被调用,当前的引用计数:%d", m_pRef->m_RefCount);
return *this;
}
template <class T>
T& Auto_Ptr<T>::operator*() { return *(m_pRef->m_pTtr); }
template <class T>
T* Auto_Ptr<T>::operator->() { return (m_pRef->m_pTtr); }
template <class T>
Auto_Ptr<T>::~Auto_Ptr()
{
cout << "析构函数在调用" << endl;
if ((--m_pRef->m_RefCount) == 0)
{
cout << "删除" << endl;
delete m_pRef;
m_pRef = nullptr;
}
}
int main(void)
{
Auto_Ptr<int>* pPtr = nullptr;
{
Auto_Ptr<int> g_ptr;
{
//声明一个ptr1的智能指针
Auto_Ptr<int> ptr1(new int(4));
printf("%d\n", *ptr1);
//将生存期小的ptr1赋值给生存期更大的g_ptr;
g_ptr = ptr1;
}
//new int(4)没有销毁
Auto_Ptr<int> ptr2(new int(3));
g_ptr = ptr2;//g-ptr --> 新的智能指针
Auto_Ptr<int>* pPtr = &ptr2;
printf("%d\n", *(*pPtr));
}
system("pause");
return 0;
}
设计模式系列 https://blog.csdn.net/nie2314550441/article/details/105849726