Вход/Регистрация
Примеры использования Паттерн 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;i<ind;i++) objs[i]->FreeInst;

 }

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

 void Do {

for(int i=0;i<ind;i++) objs[i]->Do1;

 }

};

void main {

  • Читать дальше
  • 1
  • 2
  • 3
  • 4
  • 5

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: