Аннотация:
Особенностью Singleton является то, что он гарантирует существование объекта в единственном экземпляре, а самое главное, то, что он создается в тот момент, когда это требуется клиенту. Последующие попытки конструирования объекта приводят лишь к возвращению клиенту ссылки на уже существующий объект, но не к созданию нового.
Во первых, статья очень хорошая и полезная, спасибо. Применил в реальной программе я этот сингелтон и остался очень доволен. Но мне надо было несколько изменить поведение исходного класса. У меня ситуация такая: есть клиент, который шлёт запросы на сервер, на сервере есть класс, который создаёт и хранит необходимые для обработки этих запросов таблицы. Но беда в том, что после обработки очередного запроса мне не надо уничтожать объект, т.к. эти запросы идут сериями по многу штук подряд, а удалять объект надо в конце серии... Я сделал во что:
template <class T>
T* Singleton<T>::Instance()
{
if(!_self)
{
_self=new T;
_refcount++; // вот это
}
_refcount++;
return _self;
}
Но выглядит на мой взгляд коряво. Может есть какие-то паттерны на этот случай?
Ну, в довесок хочу воткнуть так вот полу-смарт указатель:
Все таки непонятно, откуда пошла дурацкая мода в с++ коде давать данным-членам класса символ подчеркивания в качестве префикса? То есть, и так ясно откуда...
Но ведь c++ не java... Например на MCVC++ код с такими префиксами не компилируется иногда. Ведь сказано же, зарезервировано под надобности компиляторов. Или это специально так отформатировано, чтобы читать было красивее? ;)
А статья действительно хорошая, удивило то что почти не пересекается с [3] ;)
Интересно обсудить эту тему.
Например у меня есть синглтон — менеджер памяти, синглтон — БД-клиент, и т.д.
Тогда менеджер памяти должен "уходить" последним, поскольку другие с-тоны могут освобождать память в своих деструкторах. Интересный вариант есть в loki. Я реалиовал свою модель. феслт кому интересно, могу поделиться или обсудить где-нить в С++ форуме.
Serge.
Hасколько проще была бы жизнь, если бы она была в исходниках.
Я тоже тут недавно боролся с глобальными методами и классами, в итоге я отказался от глобального класса, а зделал набор интерфейсов который упрятал в namespace. Там же я определил локальные переменные и локальную instance класса switcher, который имеет только конструктор и деструктор и занимается инициализацией и уничтожением внутренних данных функционального набора при запуске-выходе из программы.
include "myinterface.h"static struct __Switcher
{
__Switcher() { constructor(); }
~__Switcher() { destructor(); }
} theSwitcher;
static int* InterfaceData;
static void constructor()
{
InterfaceData = new int(0);
}
static void destructor()
{
delete InterfaceData;
}
bool myinterface::Start()
{
//здесь можно принять какието параметры из вне
//так же можно проверить если другие неоходимые интерфесы
//уже запущенны, проинициализированны
}
bool myinterface::Stop()
{
//(для примера) Мне требовалась остановка потоков без прекращения работы программы
}
bool myinterface::DoAction()
{
printf( "Hallo from do_action [%d]", InterfaceData++ );
}
То есть мне не надо было заботится об инстансировании глобального объекта, мне почему то показалось жто важным, хотя он и присутсвует тоже.
Снимается проблема со множественным инстансированием.
Проблемы с наследованием практически нет.
Пользователь видит только то, что ему видеть пологается и предлагается.
Спасибо за статью.
Однако хотелось бы отметить, что в ней не указан т.н. Meyer's Singleton.
Он более безопасно (имхо) решает проблему удаления одиночки, достаточно прозрачен в реализации, и его я в основном и использую
struct theT
{
static T& Instance () {
static T self; // здесь можно провести инициализацию связки стат. объектов.
// для этого удобно использовать конструктор локального
// класса, статическая переменная которого определяется
// в этом методеreturn self;
}
};
Этот прием описан у Александреску в главе 6 Implementing Singletons
Я знаком с этим типом 'реализации' синглетона, однако не считаю его полноценным синглетоном с точки зрения постановки задачи в начале статьи — возможность управлять временем создания и удаления объекта. В реализации предлагаемой Meyers'ом объект все равно создается и удаляется статически, то есть те проблемы которые описаны в начале статьи статьи остаются в силе. Единственную задачу которую решает данная реализация — это гарантия того, что объект существует в единственном экземпляре, а этого не достаточно.
Объект создается при первом обращении и разрушается по выходу и программы.
Гарантируется, что чем позже объект создан, тем раньше он будет разрушен.
Из этого следует, что проблемы возникнут, если в деструкторе одиночка класса A обращается к одиночке класса В, а тот уже разрушен. Это возможно в случае, если одиночка класса В создан позже одиночки класса А... На самом деле интересно, что будет если при закрытии программы после того, как разрушен одиночка B, вызывается деструктор одиночки А, который обращается к одиночке класса В. Будет ли создан заново экземпляр класса В или произойдет сбой?
Здравствуйте, null, Вы писали:
N>Потому, что идея заключается в отказе от применения статических объектов.
Какая связь между ссылкой и статическим объектом?
Singleton не должен ни при каких условиях возвращать указатель, дабы не было никаких соблазнов и ошибок.
Здравствуйте, null, Вы писали:
n> Единственную задачу которую решает данная реализация — это гарантия того, n> что объект существует в единственном экземпляре,
Даже эту задачу данная реализация успешно решает только при условии отсутствия
многопоточности. В это решение корректно синхронизацию добавить весьма проблематично.
Posted via RSDN NNTP Server 1.6 RC1
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Ещё одно дополнение. Для singleton нужно переопределять операторы присваивания и конструктор копирования. Наиболее разумная реакция, на мой взгляд, — генерация исключения. Тогда и проблем с
Ну какая ж это разумная реализация?
Закрытыми их надо делать...
"Евгений Коробко" <12408@news.rsdn.ru> wrote in message news:466069@news.rsdn.ru... > Здравствуйте, Дмитрий Федоров, Вы писали: > > Ещё одно дополнение. Для singleton нужно переопределять операторы присваивания и конструктор копирования. Наиболее разумная реакция, на мой взгляд, — генерация исключения. Тогда и проблем с > > Singleton s=*Singleton.Instance() > > не будет.