Доброго времени суток всем нам!
Понадобился мне тут сабж... в boost'е ничего подобного, к моему глубочайшему удивлению, не обнаружилось; гуглевание по словам "C++ singleton thread safe" выдало лишь массу ссылок на "общие слова", по прочтении которых наваялось вот такое:
// interface
template <class _Class_t>
class Singleton
{
// construction/destruction
protected:
Singleton(void);
~Singleton(void);
// copying/assignment - disabled and thus not implemented
private:
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
// object creator/accessor
public:
static _Class_t& GetObject(void);
// attributes
private:
class Locker: public CRITICAL_SECTION
{
friend class Singleton<_Class_t>;
Locker(void);
~Locker(void);
void Enter(void);
void Leave(void);
};
static Locker m_objectLocker;
};
// Singleton<> implementation
template <class _Class_t>
inline Singleton<_Class_t>::Singleton(void)
{
}
template <class _Class_t>
inline Singleton<_Class_t>::~Singleton(void)
{
}
template <class _Class_t>
_Class_t& Singleton<_Class_t>::GetObject(void)
{
m_objectLocker.Enter();
static _Class_t* pObject;
if (pObject == NULL)
{
pObject = new _Class_t();
}
m_objectLocker.Leave();
return (*pObject);
}
template <class _Class_t>
typename Singleton<_Class_t>::Locker Singleton<_Class_t>::m_objectLocker;
// Singleton<>::Locker implementation
template <class _Class_t>
inline Singleton<_Class_t>::Locker::Locker(void)
{
::InitializeCriticalSection(this);
}
template <class _Class_t>
inline Singleton<_Class_t>::Locker::~Locker(void)
{
::DeleteCriticalSection(this);
}
template <class _Class_t>
inline void Singleton<_Class_t>::Locker::Enter(void)
{
::EnterCriticalSection(this);
}
template <class _Class_t>
inline void Singleton<_Class_t>::Locker::Leave(void)
{
::LeaveCriticalSection(this);
}
Метод использования очевиден:
class MyOneAndOnly: public Singleton<MyOneAndOnly> { ... };
MyOneAndOnly::GetObject().some_method();
Теперь собственно проблемы/вопросы:
Обращение к методам MyOneAndOnly потенциально возможно из конструкторов/деструкторов глобальных объектов (почему pObject и создается в куче). С первыи проблем, как я понимаю не возникнет, так как при первом же общении произойдет вызов new _Class_t. А вот деструкторами все хуже, потому как никаких гарантий, что уже не был разрушен Locker, у меня нет.
Это можно как-то преодолеть?
Очевидно, что когда-то нужно вызвать delete pObject — но как это сделать "безопасно" (то есть, с гарантией, что все глобальные объекты уже разрушены)? Копать в сторону atexit()?
Я правильно понимаю, что реализовать singleton для класса, который не имеет конструктора по умолчанию, невозможно?
P.S.
В ожидании ответов пошел читать
Паттерн Singleton (Одиночка). Примеры использованияАвтор(ы): Дмитрий Федоров
Дата: 14.11.2002

[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]