ポリシーで作成されたAlexandrescuのシングルトンを調べていましたが、これは興味深い設計です。( http://loki-lib.sourceforge.net/html/a00670.html )
ただし、彼は最初に、シングルトンの一意性を保証する必要があると説明していますが、これには同意します。しかし、ポリシーの実装を見ると、T で指定された引数で new 演算子を呼び出すポリシー CreateWithNew があります。これは、コンストラクターがパブリックである必要があることを意味します。つまり、singletonHolder を作成するユーザーは、そのクラスを自分自身で直接インスタンス化することもできます。
明らかにそれはまだ素晴らしいデザインですが、何か重要なことを見逃していないか、それとも彼が用途の広いデザインのために独自性を犠牲にしていないかを確認したかっただけです.
ありがとう!
テスト例: 次のクラスには、Singleton クラスである TestObject と、new を使用してシングルトンを割り当てる単純な createViaNewPolicy があります。これを機能させるには、TestObject のコンストラクターを public にする必要があることに注意してください。
//////////////////////////////////////////////////////////////////////////
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;
}