Alexandrescu带有策略的单例

Alexandrescu singleton with policies

本文关键字:单例 有策略 Alexandrescu      更新时间:2023-10-16

我正在研究Alexandrescu使用策略创建的单例,这是一个有趣的设计。(http://loki-lib.sourceforge.net/html/a00670.html)

然而,他首先解释说你应该保证Singleton的唯一性,我同意这一点。但是当你看策略实现时,他有一个策略CreateWithNew,它调用了t提供的参数上的new操作符,这意味着构造函数必须是公共的,这意味着任何创建singletonHolder的用户也可以直接自己实例化该类。

显然这仍然是一个很好的设计,但我只是想确定我是否错过了一些重要的东西,或者他是否为了一个通用的设计而牺牲了独特性。

谢谢!

测试示例:下面的类有一个TestObject,它是单例类,还有一个简单的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;
}

CreateUsingNew就是策略。使用它的方式是作为Singleton类中的模板模板参数。因此,单例类将具有以下布局(从现代c++设计中提取):

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

在这里,对象的创建只能通过Instance方法完成。然后,该方法读取(从Loki的链接中提取):

 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();

本身,单个对象的每个构造方法都是私有的,并且构造策略的底层实现只能通过公共MakeInstance方法

访问。