Alexandrescu单身人士与政策

时间:2014-05-29 15:33:10

标签: c++ templates singleton policies

我正在调查使用政策制作的亚历山大夫斯克的单身人士,这是一个有趣的设计。 (http://loki-lib.sourceforge.net/html/a00670.html

然而,他首先解释说你应该保证单身人士的独特性,我同意这一点。但是当你查看策略实现时,他有一个策略CreateWithNew,它在T提供的参数上调用new运算符,这意味着构造函数必须是公共的,这意味着任何创建singletonHolder的用户也可以直接自己实例化该类。 / p>

显然它仍然是一个不错的设计,但我只是想确定我是否错过了一些重要的东西,或者他是否牺牲了多功能设计的独特性。

谢谢!

一个测试示例: 下面的类有一个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 个答案:

答案 0 :(得分: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();

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