1

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

然而,他首先解释说你应该保证单例的唯一性,我同意这一点。但是当你查看策略实现时,他有一个策略 CreateWithNew,它在 T 提供的参数上调用 new 运算符。这意味着构造函数必须是公共的,这意味着创建 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;
}
4

1 回答 1

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方法访问

于 2014-05-29T15:59:02.103 回答