Примеры использования Паттерн Singleton (Одиночка) | страница 5
> Client(){
> objs[0]=NULL;objs[1]=NULL;ind=0; }
> ~Client() {
> for(int i=0;i
> }
> void Add(base *p){if(ind<2) objs[ind++]=p;}
> void Do() {
> for(int i=0;i
> }
>};
>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 этот метод переопределен с учетом подсчета ссылок, то программа работает именно так как ожидается.
Применение шаблонов языка C++.
Альтернативой приведенной выше реализации может служить реализация класса Singleton при помощи шаблонов языка С++. Преимущество такого подхода заключается в автоматической параметризации метода Instance(), что приводит к отсутствию необходимости переопределять его в классах потомках. По изложенным ранее причинам конструктор класса-потомка также должен быть объявлен защищенным, а деструктор виртуальным. Кроме того, базовый класс Singleton должен быть объявлен другом класса наследника, поскольку метод Instance() базового класса в этой модели создает объект производного класса.
>template
>class Singleton {
> static T* _self;
> static int _refcount;
>protected:
> Singleton(){}
> virtual ~Singleton(){_self=NULL;}
>public:
> static T* Instance();
> void FreeInst();
>};
>template
>T* Singleton
>template
>int Singleton
>template
>T* Singleton
> if(!_self) _self=new T;
> _refcount++;
> return _self;
>}
>template
>void Singleton
> if(--_refcount==0) delete this;
>}
>class Derived: public Singleton
>protected:
> Derived(){}
> friend class Singleton
>};
>int main(int argc, char* argv[]) {
> Derived *p = Derived::Instance();
> …
> …
> …
> p->FreeInst();
> return 0;
>}
Классы, объекты которых должны существовать в единственном экземпляре, просто наследуются от шаблонного класса Singleton. Такой подход, однако, не позволяет создать иерархию классов во главе с классом-интерфейсом, в которой некоторые из классов-наследников реализуют паттерн проектирования Singleton, а некоторые нет (См листинг 8). С другой стороны, применение параметризованного класса позволяет вынести код Singleton’а в отдельный файл и включать его в последствии в создаваемые приложения, обеспечивая тем самым повторное использование паттерна Singleton.