Столкнулся со следующей проблемой.
Есть класс 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."
вообще для меня не имеет смысла, либо я ее не понимаю
Здравствуйте, Radmir, Вы писали:
R>Столкнулся со следующей проблемой. R>Есть класс A и куча наследников от этого класса, R>и класс Singleton. R>Необходимо следуший алгоритм работы синлетона. R>Для всех экземпляра конкретного класса наследника должен сушестовать 1 экземпляр класса Singleton. R>т.е. R>Если у нас есть два наследника B и С. R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton. R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.
R>Вопрос: Как это можно реализовать?
R>Спасибо.
как то замысловато ты свою мысль выражаешь.
если нужен синглетон для каждого класса — сделай его шаблоном
Здравствуйте, 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();
}
Здравствуйте, 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.
Здравствуйте, Radmir, Вы писали:
R>Столкнулся со следующей проблемой.
<...> R>Если у нас есть два наследника B и С. R>То для всех экземпляров класса B должен существовать 1 эксемпляр Singleton. R>То для всех экземпляров класса С должен существовать 2 эксемпляр Singleton.
R>Вопрос: Как это можно реализовать?
R>Спасибо.
Могу предложить map по type_id, в отличии от шаблона, такой способ позволит даже в методах предка получать нужные объекты
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, crable, Вы писали:
C>Вот, штука, конечно, страшная, но работает
[поскипано] C> friend struct Accessor::singleton_accessor_t;
а так мона? C>[/ccode]
Здравствуйте, 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.
Здравствуйте, 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_defstruct 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.