printСтруктурирующие паттерны

printЗаместитель

Proxy

Назначение
Является суррогатом другого объекта и контролирует доступ к нему.

Результаты
1. Удаленный заместитель может скрыть тот факт, что объект находится в другом адресном пространстве.
2. Виртуальный заместитель может выполнять оптимизацию, например, создание объекта по требованию.
3. Защищающий заместитель и "умная" ссылка позволяют решать дополнительные задачи при доступе к объекту, например, контроль прав доступа или автоматическое уничтожение объекта при уменьшении ссылок на объект до 0.

Структура
14678.png

Реализация
// Субъект определяет общий для RealSubject и Proxy интерфейс,
// так что класс Proxy можно использовать везде, где ожидается RealSubject
class Subject {
public:
  virtual void Request()=0;
};
// Реальный субъект
class RealSubject : public Subject {
public:
  void Request();
};
// Заместитель
class Proxy: public Subject {
  RealSubject *s;
public:
  void Request() { s->Request(); }
};
Умные указатели за счет перегрузки операций обеспечивают интерфейс как у обычного указателя и автоматическое уничтожение созданных объектов.
// Умный указатель
class SmartPtr {
  Data *ptr;
public:
  SmartPtr():ptr(0) {}
  SmartPtr(const SmartPtr& p);
  SmartPtr(Data *data);
  SmartPtr& operator=(const SmartPtr&p);
  ~SmartPtr();
  Data *operator->(){ return ptr; }
  Data &operator*() { return *ptr; }
  friend bool operator==(const SmartPtr &a, const SmartPtr &b)
  { return a.ptr==b.ptr; }
};
// Данные
class Data {
  int count; // счетчик указателей
  int data;  // данные
  friend class SmartPtr;
public:
  Data():count(0),data(1){}
  SmartPtr operator&() { return SmartPtr(this); }
  int getData() const { return data; }
};
SmartPtr::SmartPtr(const SmartPtr& p) 
{ if((ptr=p.ptr)!=NULL)
    ++(ptr->count);
}
SmartPtr::SmartPtr(Data *data)
{ ptr=data;
  ++(ptr->count);
}
SmartPtr& SmartPtr::operator=(const SmartPtr&p)
{ SmartPtr t(p);
  std::swap(t.ptr,ptr);
  return *this;
}
SmartPtr::~SmartPtr()
{ if(ptr && --(ptr->count)==0)
    delete ptr; 
}
bool operator!=(const SmartPtr &a, const SmartPtr &b)
{ return !(a==b); 
}
// Использование
SmartPtr p=new Data;
cout<<p->getData()<<"\n";
loading