Another lazy programmer… Currient status : offline
RSS icon Home icon
  • Паттерн Singleton / знакомство

    Posted on апреля 16, 2009 Crol 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