-
Паттерн Singleton / знакомство
Posted on апреля 16, 2009 No commentsЧитая на днях весьма интересную книженцию [?] познакомился я с этой интересной штукой, вот и вас тоже хочу просветить.
В чем собственно суть - допустим есть у меня класс консоли, мы создаем его экземпляр в главном классе движка, а потом передаем указатели на него всем другим классам\классам-менеджерам, собственно выглядит это так:Camera_Manager = new CLREngi_Camera_Manager(Console);И все бы ничего, но когда классов много появляются вот такие конструкции:
Object_Manager = new CLREngi_Object_Manager(&matWorld,d3dDevice,Effect_Manager,Light_Manager,PhysX_Manager,Camera_Manager,Console);Потом в конструкторе нужно маятся сохраняя на объекты указатели. Вроде бы и терпимо, но есть другое решение. Давайте обратим внимание на то, что почти каждый из этих перегоняемых объектов существует в движке в единственном числе, то есть фактически объявив его статическим мы сможем получить к нему доступ в любом месте движка! Теперь о реализации, собственно в wiki можно найти разные реализации, так же thread-safe варианты на паттернах.
Я же приведу в пример самый простой рабочий вариант который я пока собрал и то как с ним работать:
#ifndef LessonClass_h #define LessonClass_h // наш тестовый класс class LessonClass{ public: // переменная для тестов int x; // указатель на самого себя, собственно и есть главня часть синглетона static LessonClass* Get; public: // тут ваш код //.. // // конструктор, дабы LessonClass(void){ // установили указатель Get = this; // дали переменной значение x = 0; }; ~LessonClass(void){ // потерли указатель на всякий случай Get = 0; }; // данную функцию использовать не обязательно, но в книге использовали её, привожу для кучности LessonClass& Get_Singleton(void){return (*Get);} }; // очень важная строчка, без нее будут ошибки линкования, так как мы не объявим статичный объект LessonClass* LessonClass::Get = 0; //все #endifИтак у нас есть файл с классом, мы его подключаем в главный класс движка и аскетично создаем экземпляр объекта:
LessonClass tuturutututu; // имя роли не играет -)Теперь посмотрим как нам вызвать его в совсем другом классе, например менеджере объектов каком-нибудь [!] :
// получаем на объект указатель LessonClass *SOMETHING = LessonClass::Get; // меняем параметр SOMETHING->x = 12; // поверьте на слово, у объекта tuturutututu переменная х стала = 12 -) // ну и еще раз!) // получаем на объект указатель LessonClass *SOMETHING2 = LessonClass::Get; // меняем параметр SOMETHING2->x = 14; // и опять поверьте на слово, у объекта tuturutututu переменная х стала = 14 -)На мой взгляд такая организация более удобна, остается только учесть некоторые возможные exceptions, когда нет объекта и нужно запретить создавать объект более одного раза [?] .
Сам я пока использовать в коде не буду этот паттерн, потому что есть ряд проблем, в частности с работой с переменными класса при помощи функций класса, у меня бывает так, что не может класс обратится к нужной области в памяти. Вообще если разберусь, то тут напишу подробнее что, да как.
Leave a reply








