Здраствуйте, Евгений Коробко. Вы писали:
ЕК> Ещё одно дополнение. Для singleton нужно переопределять операторы ЕК> присваивания и конструктор копирования. Наиболее разумная реакция, на ЕК> мой взгляд, — генерация исключения. Тогда и проблем с ЕК> ЕК> Singleton s=*Singleton.Instance() ЕК> ЕК> не будет.
А зачем кидаться исключениями, если можно запретить копирование и присваивание на этапе компиляции?
Здравствуйте, schakal, Вы писали:
s> Ну какая ж это разумная реализация? s> Закрытыми их надо делать...
s> "Евгений Коробко" <12408@news.rsdn.ru> wrote in message news:466069@news.rsdn.ru... >> Здравствуйте, Дмитрий Федоров, Вы писали: >> >> <...>
Ваше сообщение нарушает правила форумов RSDN в отношении оформления и объема цитирования.
Подобный стиль цитирования, т.е. набор нового текста в начале сообщения с последующим
цитированием всего текста оригинального сообщения (top posting) не приветствуется в форумах
RSDN.ru, более того, настоятельно рекомендую не допускать этого в дальнейшем, так как:
при таком стиле цитирования, читая набранное вверху сообщения, сложно понять,
к какой части оригинального сообщения это относится;
такой подход стимулирует избыточное цитирование, что является одним из явлений,
наиболее раздражающих пользователей RSDN.ru.
Q: Because it reverses the logical flow of conversation.
A: Why is top posting frowned upon?
Ваши читатели будут вам благодарны, если в дальнейшем вы будете цитировать из исходного
сообщения ровно столько, сколько необходимо для понимания контекста вашего ответа, а также
размещать строки своего ответа непосредственно под цитируемыми фрагментами, соответственно
разбивая исходное сообщение. Также считаю нужным обратить ваше внимание на то, что в форумах
RSDN.ru рекомендуется оформлять цитаты, помещая аббревиатуру автора оригинального сообщения
перед символом '>' в начале каждой цитируемой строки.
Плагин для Outlook Express, с легкостью позволяющий это делать, вы можете найти здесь: http://www.fidolook.com
Может быть, лично вам по каким-либо причинам более удобен формат, использованный вами
в своем ответе; также вполне возможно, что вы можете не соглашаться с соображениями,
изложенными выше. Тем не менее, обращаю ваше внимание, что предлагаемый формат сообщений
является именно тем, что предпочитает большинство активных пользователей RSDN.ru, и,
соответственно, тем, чего они ожидают для комфортного чтения. Следуя принятым здесь
обычаям, вы скорее встретите доброжелательно настроенных собеседников, готовых помочь
и пойти навстречу.
Спасибо.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Дмитрий Федоров, Вы писали:
ДФ>Особенностью Singleton является то, что он гарантирует существование объекта в единственном экземпляре, а самое главное, то, что он создается в тот момент, когда это требуется клиенту. Последующие попытки конструирования объекта приводят лишь к возвращению клиенту ссылки на уже существующий объект, но не к созданию нового.
С рождением и смертью синглетона не все так однозначно.
Синглетон создается при первом обращении, затем погибает
— по обнулению ссылок
— по "свистку" (например, по завершению модуля)
После свистка он может быть пересоздан, либо запрещен.
Свисток — это либо выход из программы (код завершения в CRT), либо ручная отмашка.
По ряду причин синглетоны, живущие в DLL, нужно убивать из DllMain(DLL_PROCESS_DETACH), а не из DLL'ского CRT.
Александреску регистрирует функции-убийцы синглетона в atexit(), я предпочитаю определять у синглетона открытый метод-убийцу или делать аналог atexit() с ручным вызовом всей коллекции в DllMain.
typedef void(*my_atexit_fn)(void*);
void schedule_my_atexit(my_atexit_fn fn, void* param); // добавляет функцию в начало спискаvoid perform_my_atexit(); // вызывает все, что было спланировано
Чтобы не возиться с подсчетом ссылок вручную, указатели на синглетон должны быть умными. Например, так:
Конструкторы (без параметров и копирования) и деструктор синглетона имеет смысл закрывать.
Чтобы single_holder мог работать, нужно объявить его другом.
Конструктор копирования вообще не существует — его объявляют, но не определяют.
class my_single
{
friend class single_holder<my_single>;
my_single(const my_single&);
protected: // если допускаем существование наследников
my_single() { . . . }
~my_single() { . . . }
public:
. . .
};
Здравствуйте, Кодт, Вы писали:
К>По ряду причин синглетоны, живущие в DLL, нужно убивать из DllMain(DLL_PROCESS_DETACH), а не из DLL'ского CRT. К>Александреску регистрирует функции-убийцы синглетона в atexit(), я предпочитаю определять у синглетона открытый метод-убийцу или делать аналог atexit() с ручным вызовом всей коллекции в DllMain.
Можно об этом подробнее?
К>Конструкторы (без параметров и копирования) и деструктор синглетона имеет смысл закрывать. К>Чтобы single_holder мог работать, нужно объявить его другом. К>Конструктор копирования вообще не существует — его объявляют, но не определяют. К>
Здравствуйте!
У меня такой вот вопрос:
1. Вот тут все говорят, что это плохой сингетон. Где мжно посмотреть на хороший?
2. Как сделать так, чтобы можно было делать наследования такого рода:
class Object:public Singleton<Object>
{
..
private:
virtual void OnCreate();
..
}
//теперь наследование от класса Object:class MyObject:public Object
{
..
private:
MyObject(){}
virtual void OnCreate()
{
MessageBeep(1);
}
..
}
//проверяем:
MyObject *obj=(MyObject*)MyObject::Instance();
obj->OnCreate(); //не заходит в MyObject
Как сделать так, чтобы можно было так делать?
Я то понимаю, что одиночка был создан ещё при инициализации Object...
N>Я знаком с этим типом 'реализации' синглетона, однако не считаю его полноценным синглетоном с точки зрения постановки задачи в начале статьи — возможность управлять временем создания и удаления объекта. В реализации предлагаемой Meyers'ом объект все равно создается и удаляется статически, то есть те проблемы которые описаны в начале статьи статьи остаются в силе.
Ответ неверный. N>Единственную задачу которую решает данная реализация — это гарантия того, что объект существует в единственном экземпляре, а этого не достаточно.
Аналогично.
n>> Единственную задачу которую решает данная реализация — это гарантия того, n>> что объект существует в единственном экземпляре,
ПК>Даже эту задачу данная реализация успешно решает только при условии отсутствия ПК>многопоточности. В это решение корректно синхронизацию добавить весьма проблематично.
Согласен, что синхронизация тут довольно проблематична, впрочем, как и в любом синглтоне. Но решить ее можно, и в соотв. топике форума С++ варинты решений приводились.
Здравствуйте, Кодт, Вы писали:
К>Свисток — это либо выход из программы (код завершения в CRT), либо ручная отмашка. К>По ряду причин синглетоны, живущие в DLL, нужно убивать из DllMain(DLL_PROCESS_DETACH), а не из DLL'ского CRT. К>Александреску регистрирует функции-убийцы синглетона в atexit(), я предпочитаю определять у синглетона открытый метод-убийцу или делать аналог atexit() с ручным вызовом всей коллекции в DllMain. К>
К>typedef void(*my_atexit_fn)(void*);
К>void schedule_my_atexit(my_atexit_fn fn, void* param); // добавляет функцию в начало списка
К>void perform_my_atexit(); // вызывает все, что было спланировано
К>
А можно глянуть, как выполняется вызов "всей коллекции в DllMain"? Каждый раз при использовании синглетона в DLL нужно не забыть и вставить цикл в DllMain? А для забывчивых есть какое нибудь средство?
Здравствуйте, Anton V. Kolotaev, Вы писали:
AVK>Объект создается при первом обращении и разрушается по выходу и программы. AVK>Гарантируется, что чем позже объект создан, тем раньше он будет разрушен. AVK>Из этого следует, что проблемы возникнут, если в деструкторе одиночка класса A обращается к одиночке класса В, а тот уже разрушен. Это возможно в случае, если одиночка класса В создан позже одиночки класса А... На самом деле интересно, что будет если при закрытии программы после того, как разрушен одиночка B, вызывается деструктор одиночки А, который обращается к одиночке класса В. Будет ли создан заново экземпляр класса В или произойдет сбой?
Однозначно сбой — такие переменные по определению создаются один раз и повторно созданы не будут.
Статья понравилась. Только есть одно замечание — есть там следующий код:
class SinglImpl: public Singleton
{
protected:
SinglImpl(){}
//объявление виртуальным в базовом классе автоматически
//дает виртуальность в производном.
~SinglImpl() { printf ("~SinglImpl\n"); }
public:
static Singleton* Instance()
{
if(!_self) _self = new SinglImpl();
_refcount++;
return _self;
}
};
Так вот, почему бы вместо двух строк комментария не поставить одно(!) слово virtual? Так на мой взгляд и нагляднее, и понятнее, и копаться в родителях нет надобности (если их много будет)...
Ну и про подчеркивания уже говорили. Я понимаю, что это собственный стиль и каждый его выбирает сам, но он затрудняет чтение, так как человек распознаёт слово целиком, а "_" этому мешает. В данной статье он употреблен грамотно, без злоупотреблений. Но это потому, что членов класса было не много. А вообще, для сравнения:
template <class _Key, class _Value, class _KeyOfValue,
class _Compare, class _Alloc> void
_Rb_tree<_Key,_Value,_KeyOfValue,
_Compare,_Alloc>::_M_erase(_Rb_tree_node<_Value>* __x)
{
// erase without rebalancingwhile (__x != 0) {
_M_erase(_S_right(__x));
_Link_type __y = _S_left(__x);
_Destroy(&__x->_M_value_field);
this->_M_header.deallocate(__x,1);
__x = __y;
}
}
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void RbTree <Key, Value, KeyOfValue, Compare, Alloc> :: Erase(RbTreeNode<Value>* x)
{
// erase without rebalancingwhile (x != 0) {
Erase( Right(x) );
LinkType y = Left(x);
Destroy( &x->ValueField );
this->Header.deallocate(x, 1);
x = y;
}
}
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Celtic Angels — Angels Sea";
Hello, ansi!
You wrote on Sat, 02 Apr 2005 13:16:09 GMT:
a> Ну и про подчеркивания уже говорили. Я понимаю, что это собственный a> стиль и каждый его выбирает сам, но он затрудняет чтение, так как a> человек распознаёт слово целиком, а "_" этому мешает. В данной статье он a> употреблен грамотно, без злоупотреблений. Но это потому, что членов a> класса было не много. А вообще, для сравнения:
a>
a> template <class _Key, class _Value, class _KeyOfValue,
a> class _Compare, class _Alloc> void
a> _Rb_tree<_Key,_Value,_KeyOfValue,
a> _Compare,_Alloc>::_M_erase(_Rb_tree_node<_Value>* __x)
a> {
a> // erase without rebalancing
a> while (__x != 0) {
a> _M_erase(_S_right(__x));
a> _Link_type __y = _S_left(__x);
a> _Destroy(&__x->_M_value_field);
a> this->_M_header.deallocate(__x,1);
a> __x = __y;
a> }
a> }
a>
a> [ccode] a> template <class Key, class Value, class KeyOfValue, class Compare, class a> Alloc> void RbTree <Key, Value, KeyOfValue, Compare, Alloc> :: a> Erase(RbTreeNode<Value>* x) { a> // erase without rebalancing a> while (x != 0) {
a> Erase( Right(x) );
a> LinkType y = Left(x); a> Destroy( &x->ValueField );
a> this->Header.deallocate(x, 1);
a> x = y;
Во блин, это оказвается стиль такой. Я то думал, что разработчики STL в Майкрософте специально так код изгадили, чтобы его читать было нельзя.
With best regards, Alexander. E-mail: fastbrain@hotbox.ru
Raurat_Ltd wrote:
> Во блин, это оказвается стиль такой. Я то думал, что разработчики STL в Майкрософте специально так код изгадили, чтобы его читать было нельзя.
Его изгадили не просто так, а со смыслом. Имена начинающиеся с 2х знаков подчеркивания (__x) или со знака подчеркивания и заглавной буквы (_Key) зарезервированы для использования реализацией стандартной библиотеки во всех контекстах.
Если бы они не использовали зарезервированные имена, то существовала бы вероятность, что некоторое имя из реализации стандартной библиотекии совпадет например с именем пользовательского макроса, и привет.
ДФ>Авторы: ДФ> Дмитрий Федоров
ДФ>Аннотация: ДФ>Особенностью Singleton является то, что он гарантирует существование объекта в единственном экземпляре, а самое главное, то, что он создается в тот момент, когда это требуется клиенту. Последующие попытки конструирования объекта приводят лишь к возвращению клиенту ссылки на уже существующий объект, но не к созданию нового.
Описанная задача исчерпывающе решена очень давно в библиотеке Loki от Андрея Александреску.
При внимательном изучении обоих решений очевидно, что уважаемым автором статьи проделана бесполезная работа
Здравствуйте, Anton V. Kolotaev, Вы писали:
AVK>Объект создается при первом обращении и разрушается по выходу и программы. AVK>Гарантируется, что чем позже объект создан, тем раньше он будет разрушен.
да ну? и кем же это гарантируется интересно.
Re[2]: Meyers singleton: время создания и удаления
От:
Аноним
Дата:
13.10.08 15:15
Оценка:
Здравствуйте, superman, Вы писали:
S>Здравствуйте, Anton V. Kolotaev, Вы писали:
AVK>>Объект создается при первом обращении и разрушается по выходу и программы. AVK>>Гарантируется, что чем позже объект создан, тем раньше он будет разрушен.
S>да ну? и кем же это гарантируется интересно.
Стандартом C++.