crossplatform.ru

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

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Типизированный синглтон расширение, потенциальные проблемы???
ViGOur
  опции профиля:
сообщение 26.2.2013, 14:24
Сообщение #1


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Подумалось мне тут, что если взять типизированный синглтон:
template <class T>
class CTypedSingleton;
который создает-возвращает указатель на класс типа T, то при вызове:
delete p; // указатель на класс типа T
вызываться декремент счетчика ссылок у нас не будет и его нужно вызывать в ручную, что чревато ошибками!
Следовательно нужно создать некий класс обертку, который открыто унаследован от класса T и закрыто от нашего типизированного синглтона, а в нем уже переопределить operator delete, в котором собственно и вызывать наш CTypedSingleton<T>::free();

Что я и сделал в коде ниже:
собственно сам код
#include <iostream>

class CClass
{
public:
    virtual ~CClass(){  }
};

template <class T>
class CTypedSingleton;

template<class T>
class CTypedWrapper : public T, private CTypedSingleton<T>
{
public:
    void operator delete(void *p)
    {
        std::cout << "CTypedWrapper::operator delete" << std::endl;
        CTypedSingleton<T>::free();
    }
};

template <class T>
class CTypedSingleton
{
    static T* m_self;
    static int m_refcount;

protected:
    CTypedSingleton(){}
    CTypedSingleton(const CTypedSingleton&){}
    virtual ~CTypedSingleton(){ m_self = 0; }
    CTypedSingleton &operator=(const CTypedSingleton&){}

public:
  static T *init()
  {
      std::cout << "init" << std::endl;
      if(!m_self)
          m_self = new CTypedWrapper<T>;
      m_refcount++;
      return m_self;
  }

  static void free()
  {
      std::cout << "free" << std::endl;
      if( m_refcount > 0)
      {
          --m_refcount;
          if( m_refcount == 0)
          {
              delete m_self;
              m_self = 0;
          }
      }
  }
};

template <class T>
T *CTypedSingleton<T>::m_self = 0;

template <class T>
int CTypedSingleton<T>::m_refcount = 0;

int main(int , char **)
{
    CClass *p = CTypedSingleton<CClass>::init();
    delete p;

    return 0;
}
В принципе потенциальных проблем я не виже, но может это из-за того, что я пока грипую и возможно не так внимателен...
Что вы скажите?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 26.2.2013, 15:40
Сообщение #2


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

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

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




Репутация:   17  


Слушай, а почему нельзя пользоваться обычным Singleton??? Ну вот такого рода:
template <class T>
class Singleton
{
protected:
    Singleton() {}
    virtual ~Singleton() {}
public:
    static T* instance()
    {
        static T self;
        return &self;
    }
};
Чем этот синглетон будет плох? Почему его не использовать

Пример использования такой, к примеру:
class ZLogger: public Singleton<ZLogger>
{
/// anything
};
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 26.2.2013, 15:44
Сообщение #3


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


А если объектов будет много, они тяжеловесны и не все всегда нужны? :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 26.2.2013, 15:55
Сообщение #4


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

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

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




Репутация:   17  


Цитата(ViGOur @ 26.2.2013, 16:44) *
А если объектов будет много, они тяжеловесны и не все всегда нужны? :)


Ну так понятнее объяснил. Да.

Сообщение отредактировал AD - 26.2.2013, 15:56
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 26.2.2013, 16:17
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

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




Репутация:   8  


Может тогда вообще не стоит делать их синглтонами?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 26.2.2013, 17:07
Сообщение #6


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


А тогда как за нимим следить проще чтобы не плодить?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 26.2.2013, 17:14
Сообщение #7


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


ViGOur, конструктор и виртуальный деструктор рулят :) Счётчик - (опять это слово :D ) инкапсулированный статический синглтон класса
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 26.2.2013, 17:51
Сообщение #8


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

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

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




Репутация:   12  


тема синглтона, на самом деле, не такая простая, как кажется. это уже тут обсуждалось:
http://www.forum.crossplatform.ru/index.php?showtopic=8976
если делать всё по-честному, там нужны двойные локи. можно сделать ну очень красивый синглтон с типами, в С++11. но это не поддерживает msvc, например.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 26.2.2013, 20:26
Сообщение #9


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Алексей1153, читай внимательней... ;)

Iron Bug, согласен синхронизация всегда нужна. В примере я все упростил, чтобы было понятней...
Сейчас почитаю.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 26.2.2013, 20:29
Сообщение #10


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

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


Цитата(ViGOur @ 26.2.2013, 17:24) *
который создает-возвращает указатель на класс типа T, то при вызове:
delete p; // указатель на класс типа T
вызываться декремент счетчика ссылок у нас не будет и его нужно вызывать в ручную, что чревато ошибками!


что тут читать внимательнее то: при вызове delete вызовется деструктор (в случае виртуального - начиная с детей, заканчивая родителем). В родительском классе уменьшаем счётчик.

Ну а то, что ты предпочёл шаблон там, где нужно было применить виртуальное наследование - это кто ж виноват :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 20.4.2024, 7:48