Синглтон, позволяющий создавать полиморфные объекты
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 30.01.04 16:51
Оценка:
...и отвечающий за создание/уничтожение объекта.

Что хочется:

1) Все операции создания/копирования/присвоения/уничтожения закрыты.
template <class T> /* необязательно, но не понятно, как без этого */
class singleton : boost::noncopyable
{
private:
    singleton() {  }
    virtual ~singleton() { }
};

и некоторая функция instance(), которая при первом вызове инициализирует синглтон, и при всех вызовах возвращает объект класса, являющегося синглтоном.

2) Должна быть возможность создания полиморфных объектов.
class abstract : public singleton<abstract>
{
    /* .... */
};

class concrete : public abstract
{
    /* .... */
};

// как создать объект класса concrete?


Получается достичь или одно, или другое.
Некоторое решение есть в Александреску, но оно кажется малоприменимым к п.2.

Любые варианты приветствуются
Re: Синглтон, позволяющий создавать полиморфные объекты
От: Кодт Россия  
Дата: 30.01.04 17:45
Оценка:
Здравствуйте, Alxndr, Вы писали:

<>

Давай сперва без шаблонов обойдёмся. Маломало помечтаем...

Вариант №1
class abstract
{
public:
  static abstract* instance();
  .....
};

class concrete : public abstract
{
  .....
};

test() { assert( dynamic_cast<concrete*>(abstract::instance()) != NULL ); }

Сразу возникает вопрос: а что, если есть несколько классов, concrete1...concreteN ? Что вернет abstract::instance() ?

Вариант №2
class abstract
{
  .....
};

class concrete : public abstract
{
public:
  static abstract* instance();
};

Здесь оказывается непринципиальным, унаследован ли concrete от abstract — на синглетонность это не влияет.

Что тебе больше нравится?


В первом случае мы имеем дело, по большому счёту, с фабричным методом (как минимум).
Финальный класс должен быть либо известен абстрактному заранее,
либо должен регистрировать себя (да ещё проверить — не нашлись ли иные претенденты)
— на стадии линковки (а не компиляции), а то и вообще в рантайме.
Перекуём баги на фичи!
Re[2]: Синглтон, позволяющий создавать полиморфные объекты
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 30.01.04 17:50
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Что тебе больше нравится?


Первый вариант вообще плохо пахнет.
Во втором варианте — непонятно куда ты клонишь.
Re[3]: Синглтон, позволяющий создавать полиморфные объекты
От: Кодт Россия  
Дата: 31.01.04 08:39
Оценка:
Здравствуйте, Alxndr, Вы писали:

К>>Что тебе больше нравится?


A>Первый вариант вообще плохо пахнет.


Плохо, а кто спорит.
Но я же не знаю, что ты хочешь. Вот и спросил...

A>Во втором варианте — непонятно куда ты клонишь.


Ну, к примеру, тебе нужны функции instance() одного типа: abstract*(*func)(void)
Тогда пишем такую утилиту
template<class Final, class Result>
class singleton
{
public:
  static Final& final_instance() { ..... }
  static Result& common_instance() { return (Result&) final_instance(); }
};
Перекуём баги на фичи!
Re: Синглтон, позволяющий создавать полиморфные объекты
От: vdimas Россия  
Дата: 02.02.04 00:03
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>...и отвечающий за создание/уничтожение объекта.


Учитывая, что сам синглтон не может быть абстрактным классом (т.е. речь идет именно о синглтоне, а не о хелпере, правильно?) то никак, ибо это противоречит самомой сути синглтона — давать единственный экземляр своего КЛАССА. Причем, конкретного класса. Ты можешь отнаследоваться от полиморфного синглтона, но этот наследник, если хочет в честь отца называться именно синглтоном, должен давать единственный экземпляр СВОЕГО класса. (дабы не вводить в заблуждение общественность)

То, что ты просишь — суть настраиваемые (параметризируемые или абстрактные) фабрики, которые должны создавать инстансы (или один лишь инстанс, с последующим ограничением его времени жизни временем жизни фабрики, это тебе как будет угодно — ты же разработчик) некоего фабрикуемого полиморфного класса. Заметь, другого совсем класса. (В не зависимости от связи с фабрикой наследованием)

Я точно знаю, что взгляды многих на синглотоны отличаются.
Так это все мое личное IMHO, служащее мне лишь в целях классификации задач.
Т.е., если мы честно признаемся себе, что фабрика и синглтон — разные вещи, то не будем пытаться подстраивать интерфейс фабрики под фабрикуемый класс (хотя, я неоднократно наблюдал подобные бессмысленные применения сил и времени, только лишь с целью реализовать т.н. СИНГЛТОН, а нафика?)
Re: Синглтон, позволяющий создавать полиморфные объекты
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 02.02.04 10:23
Оценка:
Здравствуйте, vdimas, Вы много писали.

Ок, просто приведу пример.

Пусть есть рендер-система, причем на все приложение (например, игру) она должна быть одна, то есть логично реализовать ее в виде синглтона. Рендер-система — абстрактный класс, от него наследуются d3d-рендер-система и ogl-рендер-система.
На этапе выполнения должна быть возможнотсь создания по запросу нужной рендер-системы и гарантии того, что она будет существовать в единственном экземпляре.
Re[2]: Синглтон, позволяющий создавать полиморфные объекты
От: Oval  
Дата: 02.02.04 10:48
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, vdimas, Вы много писали.


A>Ок, просто приведу пример.


A>Пусть есть рендер-система, причем на все приложение (например, игру) она должна быть одна, то есть логично реализовать ее в виде синглтона. Рендер-система — абстрактный класс, от него наследуются d3d-рендер-система и ogl-рендер-система.

A>На этапе выполнения должна быть возможнотсь создания по запросу нужной рендер-системы и гарантии того, что она будет существовать в единственном экземпляре.

А вот такие полиморфные синглтоны кажеться еще никто не изучал:

class CRender
{
...
};

CRender& getD3DRender()
{
    class D3DRender : public CRender
    {
       ...
    };
   static D3DRender obj;
   return obj;
}

CRender& getOGLRender()
{
    class OGLRender : public CRender
    {
       ...
    };
   static OGLRender obj;
   return obj
}


Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это "сильный" синглтон.
А призводящие функции можно и друзьями базового класса сделать
Re[3]: Синглтон, позволяющий создавать полиморфные объекты
От: Андрей Галюзин Украина  
Дата: 02.02.04 14:15
Оценка:
A>>Пусть есть рендер-система, причем на все приложение (например, игру) она должна быть одна, то
A>>есть логично реализовать ее в виде синглтона. Рендер-система — абстрактный класс, от него
A>>наследуются d3d-рендер-система и ogl-рендер-система.
A>>На этапе выполнения должна быть возможнотсь создания по запросу нужной рендер-системы и
A>>гарантии того, что она будет существовать в единственном экземпляре.

O>
O> class CRender
O> {
O> ...
O> };

O> CRender& getD3DRender()
O> {
O>     class D3DRender : public CRender
O>     {
O>        ...
O>     };
O>    static D3DRender obj;
O>    return obj;
O> }

O> CRender& getOGLRender()
O> {
O>     class OGLRender : public CRender
O>     {
O>        ...
O>     };
O>    static OGLRender obj;
O>    return obj
O> }

O>


O> Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это

O> "сильный" синглтон.
O> А призводящие функции можно и друзьями базового класса сделать

А теперь о недостатках: в таком случае в коде придется явно указывать рендерер, чего автор как раз хотел избежать.
Я бы посоветовал наделить синглтон стратегией создания и не выдумывать велосипеды

Что-то вроде этого (не компилировалось и многие детали опущены).
struct RendererCreator
{
  virtual Renderer* create() = 0;
};

// имя лучше выбрать покороче ибо RendererSingleton::instance() выглядит
// несколько громоздко
class RendererSingleton
{
public:
  static set_creator(RendererCreator* value)
  {
     creator_ = value;
  }

  static Renderer& instance()
  {
     if (!instance_)
     {
       if (!creator_)
         throw std::logic_error("null creator");
       instance_ = creator_->create();
     }
     return *instance_;
  }

private:
  ~RendererSingleton();

private:
  static Renderer* instance_;
  static RendererCreator* creator_;
};


--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[4]: Синглтон, позволяющий создавать полиморфные объекты
От: Oval  
Дата: 02.02.04 19:19
Оценка:
Здравствуйте, Андрей Галюзин, Вы писали:

O>> Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это

O>> "сильный" синглтон.
O>> А призводящие функции можно и друзьями базового класса сделать

АГ>А теперь о недостатках: в таком случае в коде придется явно указывать рендерер, чего автор как раз хотел избежать.

Автор хотел на этапе выполнения иметь возможность выбрать нужный рендер. На одно положение TogleButton поставит getD3DRender(), на другое getOGLRender(). Ну и будет иннициализировать ими какой-нибудь CRender& curentRender (что никакой синглтон не запретит).

АГ>Я бы посоветовал наделить синглтон стратегией создания и не выдумывать велосипеды


Ес-но, если не нравится статическая иннициализация можно добавить всякие разные стратегии создания и управления временем жизни, далее — Александреску, Locki по вкусу. От себя — можно подумать как запретить существование обоих разнородных объектов одновременно (в рамках базового класса).

Мой вариант лишь добавляет еще один уровень защиты — защиты от наследования (впрочем это более актуально для библиотечных синглтонов)

Легче выдумывать велосипед чем моцоцикл
Re[5]: Синглтон, позволяющий создавать полиморфные объекты
От: Андрей Галюзин Украина  
Дата: 03.02.04 11:45
Оценка:
АГ>>А теперь о недостатках: в таком случае в коде придется явно указывать рендерер, чего
АГ>>автор как раз хотел избежать.

O> Автор хотел на этапе выполнения иметь возможность выбрать нужный рендер. На одно

O> положение TogleButton поставит getD3DRender(), на другое getOGLRender(). Ну и будет
O> иннициализировать ими какой-нибудь CRender& curentRender (что никакой синглтон не запретит).

Гм. Это все хорошо. Только каким образом при переключении рендерера вызывать деструктор.
В твоей затее поклацав рендерами туда-суда-обратно будем иметь полный набор, если один из них не вывалится с ошибкой при создании.

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[5]: Синглтон, позволяющий создавать полиморфные объекты
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 03.02.04 11:55
Оценка:
Здравствуйте, Oval, Вы писали:


O>>> Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это

O>>> "сильный" синглтон.

О>...


O>Мой вариант лишь добавляет еще один уровень защиты — защиты от наследования (впрочем это более актуально для библиотечных синглтонов)


Защита от наследования в этом случае — вредный побочный эффект.
Re[6]: Синглтон, позволяющий создавать полиморфные объекты
От: Oval  
Дата: 03.02.04 18:36
Оценка:
Здравствуйте, Alxndr, Вы писали:

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



O>>>> Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это

O>>>> "сильный" синглтон.

О>>...


O>>Мой вариант лишь добавляет еще один уровень защиты — защиты от наследования (впрочем это более актуально для библиотечных синглтонов)


A>Защита от наследования в этом случае — вредный побочный эффект.


То что бесполезный я и сам понимаю(хотя тоже спорно — а если в команде разработчиков несколько человек?), а вот обоснуй вредность
Re[2]: Синглтон, позволяющий создавать полиморфные объекты
От: amark  
Дата: 03.02.04 21:30
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Пусть есть рендер-система, причем на все приложение (например, игру) она должна быть одна, то есть логично реализовать ее в виде синглтона. Рендер-система — абстрактный класс, от него наследуются d3d-рендер-система и ogl-рендер-система.

A>На этапе выполнения должна быть возможнотсь создания по запросу нужной рендер-системы и гарантии того, что она будет существовать в единственном экземпляре.

Могу рассказать, как подобное было реализовано в нашей системе, соответственно, под наши нужды. Имелось (имелись — так правильнее) приложение, которое было сурово заточено под Oracle. Заказчик захотел (его деньги — его право) поиметь рядом интерфейс с MS SQL (вроде похоже, я о различиях и подобии задач ). Дальше — начинается порнография, поэтому детей и морально неустойчивых — плз, уберите.
Дело в том, что наши германские коллеги, как оказалось, программируют так же, как и маршируют (Звыняюсь за искаженную цитату из Лиддел Гарта . И я не настаиваю на том, что все немцы придерживаются этого стиля). Суть в чем — обилие static функций, а именно через них была реализована вся функциональность.
Выход?
Я уже слышу крики refactoring !, постепенно переходящие в "Царя, царя !", каковые со временем переходят в "Шайбу ! Шайбу!". Сорри, увлёкся классикой
Я уже не помню, на пиве или после оного возникло и решение — изваять синглтона-полиморфа. А проще всего его оказалось породить в нашем монстроидальном синглтоне, который был ответственен за доступ к некоторым глобальным настройкам. А когда дело коснулось реализации — дык, switch, в зависимости от настройки. Т.е., к чему я клоню — на некоторых этапах (особенно инициализации) системы ОО подход — увы, не то.... (либо — просто вырождается в те методы, которые его породили )

В общем, так. В пузе нашего монстра (в смысле "канкретнава" синглтона) был добавлен код

switch(nSQLServer)
{
    case blmOracle:
       return new UOracleSyntax;
       break;

    case blmMSSql:
       return new UMSSQLSyntax:
       break;

    default:
       ASSERT(0);     
}


В заключение. Из Шеллинга (19-й век). "Для того, чтобы понять систему, нужно находиться вне её." А чтобы построить?
Re[3]: Синглтон, позволяющий создавать полиморфные объекты
От: amark  
Дата: 03.02.04 21:47
Оценка:
Да, забыл заметить. В предыдущей мессаге, что UOracleSyntax, что UMSSQLSyntax — суть наследники одного и того же абстрактного класса.
Re[3]: Синглтон, позволяющий создавать полиморфные объекты
От: _Macintosh_ Израиль  
Дата: 04.02.04 08:33
Оценка:
Здравствуйте, Oval, Вы писали:

O>А вот такие полиморфные синглтоны кажеться еще никто не изучал:


[]

O>Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это "сильный" синглтон.

O>А призводящие функции можно и друзьями базового класса сделать

Где-то я такое уже читал... Сейчас вспомню... А, точно, Александреску затрагивал тему анонимных классов и пришел к таким же результатам
Re[4]: Синглтон, позволяющий создавать полиморфные объекты
От: Oval  
Дата: 04.02.04 15:41
Оценка:
Здравствуйте, _Macintosh_, Вы писали:

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


O>>А вот такие полиморфные синглтоны кажеться еще никто не изучал:


_M_>[]


O>>Достоинства — Производные классы анонимные и финальные — хрен отнаследуешься. Я бы назвал это "сильный" синглтон.

O>>А призводящие функции можно и друзьями базового класса сделать

_M_>Где-то я такое уже читал... Сейчас вспомню... А, точно, Александреску затрагивал тему анонимных классов и пришел к таким же результатам

Да, но не применительно к полиморфным синглтонам
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.