Расширенный Синглетон
От: Radmir Россия  
Дата: 11.11.05 06:55
Оценка:
Столкнулся со следующей проблемой.
Есть класс A и куча наследников от этого класса,
и класс Singleton.
Необходимо следуший алгоритм работы синлетона.
Для всех экземпляра конкретного класса наследника должен сушестовать 1 экземпляр класса Singleton.
т.е.
Если у нас есть два наследника B и С.
То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton.
То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.

Вопрос: Как это можно реализовать?

Спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Лучше спросить дорогу чем заблудиться
Re: Расширенный Синглетон
От: Аноним  
Дата: 11.11.05 07:56
Оценка:
Пытаюсь, но не могу понять, что тебе надо.

Для начала, сингелтон — это одиночка.
Т.е. это когда гарантированно существует не более одного объекта заданного класса.
Потому твоя фраза
"То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton."
вообще для меня не имеет смысла, либо я ее не понимаю
Re: Расширенный Синглетон
От: night_beast СССР  
Дата: 11.11.05 08:12
Оценка: +1 :)
Здравствуйте, Radmir, Вы писали:

R>Столкнулся со следующей проблемой.

R>Есть класс A и куча наследников от этого класса,
R>и класс Singleton.
R>Необходимо следуший алгоритм работы синлетона.
R>Для всех экземпляра конкретного класса наследника должен сушестовать 1 экземпляр класса Singleton.
R>т.е.
R>Если у нас есть два наследника B и С.
R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton.
R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.

R>Вопрос: Как это можно реализовать?


R>Спасибо.


как то замысловато ты свою мысль выражаешь.

если нужен синглетон для каждого класса — сделай его шаблоном
Re: Расширенный Синглетон
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 11.11.05 08:13
Оценка:
Здравствуйте, Radmir, Вы писали:

R>Столкнулся со следующей проблемой.

R>Есть класс A и куча наследников от этого класса,
R>и класс Singleton.
R>Необходимо следуший алгоритм работы синлетона.
R>Для всех экземпляра конкретного класса наследника должен сушестовать 1 экземпляр класса Singleton.
R>т.е.
R>Если у нас есть два наследника B и С.
R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton.
R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.

R>Вопрос: Как это можно реализовать?


R>Спасибо.


Шаблон. Продемонстрирую идею.
template <typename Class> 
Singleton & GetSingletonForMe(const Class &) // не используем этот параметр
{
    static Singleton singleton;
    return singleton; 
}
// ...
// Вызов в методе класса А

A::A::DoX()
{
  GetSingletonForMe(*this).DoIt();
}

// В классе B
B::B::DoY()
{
   GetSingletonForMe(*this).DoIt();
}


Идея понятна?
Re[2]: Расширенный Синглетон
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 11.11.05 08:21
Оценка:
Здравствуйте, BitField, Вы писали:

Блин, наверное лучше внести метод в класс Синглетона
BF>

class Singleton
{
public:
   template<typename Class>
   Singleton & GetInstanceFor(const Class &)
   {
      static Singleton singleton;
      return singleton; 
   }
   
private:
   Singleton(); // это реализуем 
   Singleton(const Singleton &); // а это нет  
   Singleton & operator=(const Singleton &);  // и это нет
};


A::A::DoX()
{
  Singleton::GetInstanceFor(*this).DoIt();
}

B::B::DoY()
{
  Singleton::GetInstanceFor(*this).DoIt();
}
Re[3]: Расширенный Синглетон
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 11.11.05 08:26
Оценка:
Здравствуйте, BitField, Вы писали:


Вот что бывает, когда сначала пишешь, а потом думаешь

BF>>

BF>class Singleton
BF>{
BF>public:
BF>   template<typename Class>
BF>   static Singleton & GetInstanceFor(const Class &)
BF>   {
BF>      static Singleton singleton;
BF>      return singleton; 
BF>   }
   
BF>private:
BF>   Singleton(); // это реализуем 
BF>   Singleton(const Singleton &); // а это нет  
BF>   Singleton & operator=(const Singleton &);  // и это нет
BF>};


BF>A::A::DoX()
BF>{
BF>  Singleton::GetInstanceFor(*this).DoIt();
BF>}

BF>B::B::DoY()
BF>{
BF>  Singleton::GetInstanceFor(*this).DoIt();
BF>}

BF>
Re: Расширенный Синглетон
От: crable США  
Дата: 11.11.05 08:41
Оценка:
Здравствуйте, Radmir, Вы писали:

R>Столкнулся со следующей проблемой.

R>Есть класс A и куча наследников от этого класса,
R>и класс Singleton.
R>Необходимо следуший алгоритм работы синлетона.
R>Для всех экземпляра конкретного класса наследника должен сушестовать 1 экземпляр класса Singleton.
R>т.е.
R>Если у нас есть два наследника B и С.
R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton.
R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.

R>Вопрос: Как это можно реализовать?


R>Спасибо.


Вот, штука, конечно, страшная, но работает

struct singleton_t
{
private:
        singleton_t();

        template <typename T, typename U> friend class holder_t;
};

template <typename Singleton, typename Accessor>
struct holder_t
{
        friend struct Accessor::singleton_accessor_t;
private:
        static Singleton *instance();
};

template <typename Accessor>
struct singleton_def
{
        typedef holder_t<singleton_t, Accessor> type;
};

struct A
{
        typedef A singleton_accessor_t;
        void f()
        {
                // так можно
                singleton_def<A>::type::instance();
                // а так нет
                //singleton_def<B>::type::instance();
        }
};

struct B
{
        typedef B singleton_accessor_t;
        void f()
        {
                singleton_def<B>::type::instance();
        }
};
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[2]: Расширенный Синглетон
От: Radmir Россия  
Дата: 11.11.05 09:59
Оценка:
Ошибка линковки

DataProvider error LNK2019: unresolved external symbol "private: static struct singleton_t * __cdecl holder_t<struct singleton_t,struct A>::instance(void)" (?instance@?$holder_t@Usingleton_t@@UA@@@@CAPAUsingleton_t@@XZ) referenced in function "public: void __thiscall A::f(void)" (?f@A@@QAEXXZ)

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Лучше спросить дорогу чем заблудиться
Re[4]: Расширенный Синглетон
От: Radmir Россия  
Дата: 11.11.05 09:59
Оценка:
Не совсем ясно вот это.
BF>>A::A::DoX()
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Лучше спросить дорогу чем заблудиться
Re: Расширенный Синглетон
От: Erop Россия  
Дата: 11.11.05 10:11
Оценка: 1 (1)
Здравствуйте, Radmir, Вы писали:

R>Столкнулся со следующей проблемой.

<...>
R>Если у нас есть два наследника B и С.
R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton.
R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.

R>Вопрос: Как это можно реализовать?


R>Спасибо.


Могу предложить map по type_id, в отличии от шаблона, такой способ позволит даже в методах предка получать нужные объекты
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Расширенный Синглетон
От: crable США  
Дата: 11.11.05 10:17
Оценка: 2 (1)
Здравствуйте, Radmir, Вы писали:

R>Ошибка линковки


R>

R>DataProvider error LNK2019: unresolved external symbol "private: static struct singleton_t * __cdecl holder_t<struct singleton_t,struct A>::instance(void)" (?instance@?$holder_t@Usingleton_t@@UA@@@@CAPAUsingleton_t@@XZ) referenced in function "public: void __thiscall A::f(void)" (?f@A@@QAEXXZ)


Нда... а чего ты собственно ожидал? Я идею подал, естественно реализаций методов нет.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[4]: Расширенный Синглетон
От: Radmir Россия  
Дата: 11.11.05 10:28
Оценка:
Спасибо. Сделал. РАБОТАЕТ !!!!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Лучше спросить дорогу чем заблудиться
Re[2]: Расширенный Синглетон
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 11.11.05 10:32
Оценка:
Здравствуйте, crable, Вы писали:

C>Вот, штука, конечно, страшная, но работает

[поскипано]
C> friend struct Accessor::singleton_accessor_t;
а так мона?
C>[/ccode]


Я как то от gcc получил за похожее по рукам.
Re[5]: Расширенный Синглетон
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 11.11.05 10:34
Оценка:
Здравствуйте, Radmir, Вы писали:

R>Не совсем ясно вот это.

R>
BF>>>A::A::DoX()
R>


сорри, прогнал
Ну это я к примеру показал, как получить доступ к синглетону_для_А из какой нить функции класса А

То есть должно быть
void A::DoX()
{
///
}



Но тут вот подумал еще:
1. я использую параметр const Class & для того, чтобы указать, для какого класса получить синглетон. Наверное, лучше сделать const Class * -- чтобы можно было получить нужный синглетон и в статических методах -- вызовом Singleton::GetInstanceFor(static_cast<A*>(NULL))

2. Возвращаемый синглетон определяется статически, то есть
сlass D: public B { ... }
B * pB = new D;

Singleton::GetInstanceFor(pB) -- вернет синглетон для B (а не для D)

Решением может быть или виртуальная фунция, возвращяющая синглетон (но тогда ее обязательно определять в каждом классе), или же map по type_id, как тут уже выше предлагали( но это ж еще и rtti включать)

3. Если к синглетону должны иметь доступ только из методов класса, то я думаю, стоит взять решение от crable.
Re[3]: Расширенный Синглетон
От: crable США  
Дата: 11.11.05 10:41
Оценка: 4 (1)
Здравствуйте, BitField, Вы писали:

BF>Здравствуйте, crable, Вы писали:


C>>Вот, штука, конечно, страшная, но работает

BF>[поскипано]
C>> friend struct Accessor::singleton_accessor_t;
BF>а так мона?
C>>[/ccode]


BF>Я как то от gcc получил за похожее по рукам.


Ну, я на эту тему стандарт подробно не изучал

Зато это должно работать:
struct singleton_t
{
private:
        singleton_t();

        template <typename T, typename U> friend class holder_t;
};

template <typename Singleton, typename Accessor>
struct holder_t
{
protected:
        static Singleton *instance();
};

template <typename Accessor>
struct singleton_def
{
        typedef holder_t<singleton_t, Accessor> type;
};

// можно и без singleton_def
struct A: private holder_t<singleton_t, A>::type
{
        void f()
        {
                singleton_def<A>::type::instance();
                // или просто
                instance();
        }
};

struct B: private singleton_def<B>::type
{
        void f()
        {
                instance();
                // а так нельзя
                //singleton_def<A>::type::instance();
        }
};
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[5]: Расширенный Синглетон
От: crable США  
Дата: 11.11.05 10:43
Оценка:
Здравствуйте, Radmir, Вы писали:

R>Спасибо. Сделал. РАБОТАЕТ !!!!


Пожалуйста.
здесь
Автор: crable
Дата: 11.11.05
еще вариант. более переносимый и, пожалуй, более соответсвующий стандарту.
The last good thing written in C was Franz Schubert's Symphony No. 9.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.