crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

5 страниц V  « < 2 3 4 5 >  
Ответить в данную темуНачать новую тему
> Шаблон проектирования Singleton (одиночка), подбираю подходящий для моей задачи
Litkevich Yuriy
  опции профиля:
сообщение 27.9.2009, 21:16
Сообщение #31


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


В итоге получилось так:
singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H

class Session
{
private:
    static Session    *p_this;
    static int        cnt;
    
private:
    Session();
    Session(const Session &){} // конструктор копирования, не использует побитовое копирование
    ~Session(){}
    Session& operator=(const Session&){return *this;}
    
public:
    static Session *InitInstance();    /*!< Создает экземпляр класса. */
    static void        FreeInstance();    /*!< Удаляет экземпляр класса. */

};

#endif //

singleton.cpp
/*!
*    \file    singleton.cpp
*    \brief    Реализация класса "Управлние сессиями".
*/
#include <QDir>
#include "singleton.h"

//определяем переменные и константы
Session *Session::p_this=0;
int Session::cnt=0;

Session::Session()
{
    // Инициализация внутренних прикладных потрохов

}

// Псевдоконструктор
Session *Session::InitInstance()
{
    if( !p_this)
    {
        p_this = new Session();
    }

    cnt++;
    return p_this;  
}

// Псевдодеструктор
void Session::FreeInstance()
{
    if (cnt>0)
        cnt--;
    else
        return;

    if (cnt==0)
    {
        delete p_this;
        p_this = 0;
    }
}

//===========================================================
//        Всякие внутренние прикладные функции
//===========================================================
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 27.9.2009, 21:47
Сообщение #32


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Юрий, по твоей реализации (кстати, практически классической!) у меня только два замечания:
1. конструкторы-деструкторы, которые ты хочешь скрыть, не обязательно реализовывать с пустым телом {}, достаточно просто объявить их private;
2. учти, что эта реализация работает только в строго однопоточной модели! В многопоточной ты либо "влетишь", либо надо реализовывать Double-Check Locking. Это, впрочем, тоже классика.

А так ничего, вполне себе красиво!...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.9.2009, 23:17
Сообщение #33


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Влад @ 28.9.2009, 1:47) *
1. конструкторы-деструкторы, которые ты хочешь скрыть, не обязательно реализовывать с пустым телом {}, достаточно просто объявить их private;
они у меня с пустым телом, т.к. в моём применении они были не нужны.

Цитата(Влад @ 28.9.2009, 1:47) *
надо реализовывать Double-Check Locking.
имеется в виду для основных переменных "Одиночки" (*p_this и cnt)?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 27.9.2009, 23:56
Сообщение #34


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 28.9.2009, 0:17) *
Цитата(Влад @ 28.9.2009, 1:47) *
1. конструкторы-деструкторы, которые ты хочешь скрыть, не обязательно реализовывать с пустым телом {}, достаточно просто объявить их private;
они у меня с пустым телом, т.к. в моём применении они были не нужны.

Ну вот, раз не нужны, то можно объявлять вообще без тела!
Цитата(Litkevich Yuriy @ 28.9.2009, 0:17) *
имеется в виду для основных переменных "Одиночки" (*p_this и cnt)?

Нет. В смысле сделать так:
mutex.lock()
//<какая-то проверка>
mutex.lock()
/// что-то делается....
mutex.unlock()
mutex.unlock()

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 28.9.2009, 11:23
Сообщение #35


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Не совсем так. Правильный (имхо) пример кода приведен ниже:
template <class T>
class Singleton
{
    .........
    
private:
    static T* volatile m_me;
};

template <class T>
T& Singleton<T>::Instance()
{
    if (!m_me)
    {
        Locker lock(m_cs);
        if (!m_me)
        {
            m_me = new T;
        }
    }
    return (*m_me);
}

template <class T>
void Singleton<T>::FreeInstance()
{
    if (m_me)
    {
        Locker lock(m_cs);
        if (m_me)
        {
            delete m_me;
            m_me = NULL;
        }
    }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.9.2009, 18:45
Сообщение #36


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Влад, поясни пожалуйста свой код.

И m_cs что такое?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 28.9.2009, 20:25
Сообщение #37


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Litkevich Yuriy @ 28.9.2009, 19:45) *
Влад, поясни пожалуйста свой код.

И m_cs что такое?

Я не Влад, но могу пояснить. Собственно, m_cs указатель на объект одиночки!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.9.2009, 20:29
Сообщение #38


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


AD, указатель в его примере - m_me
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 28.9.2009, 20:46
Сообщение #39


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Ага, этот пример кода выдран с корнем из реально работающего (уж года два как... в режиме 24x7) проекта. m_me - это как раз и есть объект-одиночка, а m_cs - это объект блокировки (под MFC это критическая секция, но, в принципе, с таким же точно успехом при минимальной модификации кода может быть и posix-ный mutex). В коде принципиально, что m_me должен быть именно volatile.

Это - просто пример реализации идиомы Double-Checked Locking, а более подробно о ней может рассказать и гугл; по-моему, тема подробно освещена у классиков типа Мейерса, Саттера.... вот только не помню, у кого точно.

Сообщение отредактировал Влад - 28.9.2009, 20:49
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.9.2009, 21:13
Сообщение #40


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Влад @ 29.9.2009, 0:46) *
Double-Checked Locking
а Почему собственно Double? вроде в каждой фукции блокировка одна
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

5 страниц V  « < 2 3 4 5 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.11.2024, 1:16