Здравствуйте, _uncle, Вы писали:
R>>Вот подумалось. _>Настоящий программист должен сделать две вещи: определить NULL и написать самую крутую реализацию Singleton'а.
Еще он должен написать свой класс строк.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, remark, Вы писали:
R>Что конкретно ты имеешь в виду? R>Ленивость Синглтона Мейерса гарантирует создание до первого обращения. R>С разрушением правда хуже. Но зачастую такие синглтоны можно и не рушить вообще. Если, речь идёт, например, об инициализации какой-то таблицы, или открытии файла.
вот цитата из той ветки:
// Furthermore, since the instance() function contains the object, instead
// of the singleton_default class containing a static instance of the
// object, that object is guaranteed to be constructed (at the latest) in
// the first call to instance(). This permits calls to instance() from
// static code, even if that code is called before the file-scope objects
// in this file have been initialized.
Увы, но разрушение такого синглетона после всех глобальных объектов, которые им пользовались, не гарантируется.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, eao197, Вы писали:
E>>Здравствуйте, remark, Вы писали:
R>>>Какие-нибудь мысли?
E>>А чем это лучше инициализации синглетонов на основе счетчиков Шварца?
R>На основе счетчиков Шварца тебе придётся делать некое подобие DCL. R>Т.е. использовать InterlockedIncrement/InterlockedDecrement при каждом обращении. R>Во-первых, это накладывает очень большое пенальти по скорости, особенно на многоядерных машинах (ну ты сам знаешь ). R>Во-вторых, опять же проблемы с портированием. Как сделать это хорошо портируемым — вопрос (если ты, конечно, не используешь ACE ).
В данном подходе (счетчик Швардца) создается глобальный объект-инициализатор в каждой единице компиляции до использования синглтона. И предполагается как и в твоем случае, что глобальные объекты не запускают потоки при инициализации. Смотри, например, здесь. Поэтому, зачем там "InterlockedIncrement/InterlockedDecrement при каждом обращении"?
R>
Здравствуйте, Quasi, Вы писали:
Q>В данном подходе (счетчик Швардца) создается глобальный объект-инициализатор в каждой единице компиляции до использования синглтона. И предполагается как и в твоем случае, что глобальные объекты не запускают потоки при инициализации. Смотри, например, здесь. Поэтому, зачем там "InterlockedIncrement/InterlockedDecrement при каждом обращении"?
Да, действительно. Недоглядел.
Ну тогда, примерно то же самое, только кода меньше писать.
R>> Q>
R>static some_service& local = some_service(); // <----------------- R>[/ccode]
R>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.
R>Какие-нибудь мысли?
это не работает, если твой синглтон находится в статической библиотеке ,
т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет.
в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости
R>+ создаётся по первому требованию R>+ гарантированно создаётся "до main()" R>- пока не отмечены
-не будет создан вообще, если он находится в статической либе
я с этим наигрался, и не придумал ничего более умного чем ручная инициализация.
т.е.
MyLib lib;
lib.Initialize(); // здесь создаются синглтоны
R>>static some_service& local = some_service(); // <----------------- R>>[/ccode]
R>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.
R>>Какие-нибудь мысли?
A>это не работает, если твой синглтон находится в статической библиотеке , A>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет. A>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Awaken, Вы писали:
R>>>static some_service& local = some_service(); // <----------------- R>>>[/ccode]
R>>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов.
R>>>Какие-нибудь мысли?
A>>это не работает, если твой синглтон находится в статической библиотеке , A>>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет. A>>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости
R>Можно добавить видимость использования local
vc8 не выбрасывает, если get_service() используется в проекте.
Если компилятор выбрасывает, то можешь сделать так:
> R>>>static some_service& local = some_service(); // <----------------- > R>>>[/ccode] > > R>>>Теперь мы гарантируем, с одной стороны, что сервис будет создан по первому требованию, и с другой стороны, если первого требования не будет во время создания глобальных объектов, он всё равно будет создан во время создания глобальных объектов. > > R>>>Какие-нибудь мысли? > > A>>это не работает, если твой синглтон находится в статической библиотеке , > A>>т.к. конструкция чтото = someservice(); никогда не будет вызвана. в ДЛЛ это работает, в exe работает, в статической либе нет. > A>>в результате пришел к выводу что лучше все синглотоны инициализировать явно в нужной последовательости > > R>Можно добавить видимость использования local > > > vc8 не выбрасывает, если get_service() используется в проекте. > > Если компилятор выбрасывает, то можешь сделать так: > >
Но при этом в случае либы хотя бы один символ из данного cpp файла должен быть использован где-то в проекте — что в данном случае автоматически выполняется. А вот со всякими саморегистрирующимися объектами беда ...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Sergey, Вы писали:
S>На VC от выбрасывания неплохо помогает __declspec(dllexport). Т.е.,
+1
S>Но при этом в случае либы хотя бы один символ из данного cpp файла должен быть использован где-то в проекте — что в данном случае автоматически выполняется. А вот со всякими саморегистрирующимися объектами беда ...
С саморегистрирующимися объектами патологическая беда, я так общего решения пока и не нашёл...