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

Я смотрел на синглтон Александреску, созданный с помощью политик, который представляет собой интересный дизайн. ( 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 метод

Другие вопросы по тегам