Читаем Примеры использования Паттерн Singleton (Одиночка) полностью

В-третьих, конструктор класса-потомка также должен быть объявлен в защищенной секции, чтобы избежать возможности создания объекта класса напрямую, минуя метод Instance().

Листинг 7

class Singleton {

protected:

 static Singleton* _self;

 static int _refcount;

 Singleton(){}

 virtual ~Singleton() {printf ("~Singleton\n");}

public:

 static Singleton* Instance();

 void FreeInst();

};

class SinglImpl: public Singleton {

protected:

 SinglImpl(){}

//объявление виртуальным в базовом классе автоматически

 //дает виртуальность в производном.

 ~SinglImpl() {printf ("~SinglImpl\n");}

public:

 static Singleton* Instance() {

  if(!_self) _self = new SinglImpl();

  _refcount++;

  return _self;

 }

};

void main() {

 Singleton *p = SinglImpl::Instance();

 …

 …

 …

 p->FreeInst();

}

Результат работы:

~SinglImpl

~Singleton

Иногда может возникнуть ситуация, при которой клиент должен полиморфно работать с объектами, имеющими общий базовый класс, но некоторые из них реализуют паттерн Singleton, а некоторые нет. Проблема возникает в момент освобождения объектов, так как у простых классов нет механизма отслеживания ссылок, а у классов, реализующих Singleton, он есть. При вызове метода FreeInst() через указатель на базовый класс будет вызываться FreeInst() базового класса, не имеющего понятия о подсчете ссылок. Это приведет и к безусловному удалению объектов “Singleton” из памяти. Для предотвращения такого поведения следует объявить виртуальным метод FreeInst() в базовом классе и реализовать специфическое поведение метода для классов Singleton. Реализация FreeInst() в базовом классе предоставляет механизм удаления объектов, не являющихся Singleton’ами.

Листинг 8

class base {

protected:

 virtual ~base(){} //гарантируем удаление только через FreeInst()

public:

 virtual void Do1()=0;

 virtual void FreeInst(){delete this;}

};

class Simple: public base {

protected:

 ~Simple () {printf("Simple::~Simple\n");}

public:

 void Do1(){printf("Simple::Do1\n");}

};

class Singleton: public base {

 static Singleton* _self;

 static int _refcount;

protected:

 Singleton(){}

 ~Singleton () {printf("Singleton::~Singleton\n");}

public:

 static Singleton* Instance() {

  if(!_self) _self = new Singleton ();

  _refcount++;

  return _self;

 }

 void FreeInst() {_refcount--; if(!_refcount) {delete this; _self=NULL;}}

void Do1(){printf("Singleton::Do1\n");}

};

Singleton* Singleton::_self=NULL;

int Singleton:: _refcount=0;

class Client {

 base *objs[2];

 int ind;

public:

 Client(){  objs[0]=NULL;objs[1]=NULL;ind=0; }

 ~Client() {

  for(int i=0;iFreeInst();

 }

 void Add(base *p){if(ind<2) objs[ind++]=p;}

 void Do() {

  for(int i=0;iDo1();

 }

};

void main() {

 Client cl;

 cl.Add(Singleton::Instance());

 cl.Add(new Simple());

cl.Do();

}

результат работы программы:

Singleton::Do1 Simple::Do1 Singleton::~Singleton Simple::~Simple

В данном примере при разрушении объект класса Client автоматически вызываются методы FreeInst() для каждого из хранимых указателей. Благодаря тому, что этот метод объявлен виртуальным, а в классах реализующих паттерн Singleton этот метод переопределен с учетом подсчета ссылок, то программа работает именно так как ожидается.

<p>Применение шаблонов языка C++.</p>
Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных