Александреску синглтон с полисами

Я изучал синглтон Александреску, созданный с помощью политик, который представляет собой интересный дизайн. (http://loki-lib.sourceforge.net/html/a00670.html)

Однако он сначала объясняет, что вы должны гарантировать уникальность синглтона, с чем я согласен. Но когда вы смотрите на реализацию политики, у него есть политика CreateWithNew, которая вызывает оператор new для аргумента, предоставленного с T. Это означает, что конструктор должен быть общедоступным, то есть любой пользователь, создающий singletonHolder, также может непосредственно создавать экземпляр этого класса.

Очевидно, что это все еще хороший дизайн, но я просто хотел убедиться, что я пропустил что-то важное или он пожертвовал уникальностью ради универсального дизайна.

Спасибо!

Тестовый пример:
Следующий класс имеет TestObject, который является классом Singleton, и простой createViaNewPolicy, который просто использует new для выделения синглтона. обратите внимание, что конструктор TestObject должен быть публичным, чтобы это работало.

//////////////////////////////////////////////////////////////////////////
class TestObject
{
public: // change this to private (to guarantee uniqueness) but then it wont compile
TestObject() {}
int foo() {return 1;}
~TestObject() {}
};

//////////////////////////////////////////////////////////////////////////
template< class T, template <class> class CreationPolicy >
class SingletonHolder
{
public:
T* SingletonHolder<T, CreationPolicy>::Instance()
{
if (!pInstance_)
{
pInstance_ = CreationPolicy<T>::Create();
}

return pInstance_;
}
private:
static T* pInstance_;
};

template< class T, template <class> class CreationPolicy >
T* SingletonHolder<T, CreationPolicy>::pInstance_;

//////////////////////////////////////////////////////////////////////////
template<class T>
class CreateViaNew
{
public:
static T* Create()
{
return new T();
};
};

//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
SingletonHolder<TestObject, CreateViaNew> mySingletonHolder;
TestObject* testObj = mySingletonHolder.Instance();
return 0;
}

1

Решение

CreateUsingNew это просто политика. Они используют его как параметр шаблона шаблона внутри Singleton учебный класс. Таким образом, синглтон-класс будет иметь следующую компоновку (за исключением современного дизайна C ++):

class Singleton
{
Singleton& Instance();
... operations...
public:
Singleton();
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
~Singleton();
}

Там создание объекта может быть сделано только через Instance метод. В свою очередь, этот метод читает (извлечение из ссылки на Локи):

 template
<
class T,
template <class> class CreationPolicy,
... some other arguments...
>
void SingletonHolder<T, CreationPolicy,
...some other arguments...>::MakeInstance()
{
... stuff ...
if (!pInstance_)
{
if (destroyed_)
{ /* more stuff */ }
pInstance_ = CreationPolicy<T>::Create();
/* even more stuff */
}
}

Таким образом, линия, где происходит волшебство pInstance = CreationPolicy<T>::Create();

Сам по себе каждый метод построения для объекта Singleton является частным, а базовая реализация политики построения может быть доступна только через открытый доступ. MakeInstance метод

0

Другие решения


По вопросам рекламы [email protected]