ページ 1 / 1
シングルトンクラスのテンプレート化
Posted: 2009年12月29日(火) 22:04
by kazuoni
お邪魔します。
現在、シングルトンクラスのテンプレート化で悩んでいます。
今自分は添付ファイルSingleton.txtのようにシングルトンクラスを管理しています。
ただ、シングルトンクラスのたびに
GetInstance
DeleteInstance
Order
メソッドを定義しなければいけないので、
これを今の呼び出し方と同様かつ、上記の関数をテンプレート化できないかと考えています。
個人的には、添付ファイルVirtualClass.txt
のような感じでテンプレートクラスを用意し、
シングルトンクラスにしたいクラスを
このTemplateForSingletonクラスから派生させることができたら
なんて思っていますが、このままだと派生クラス(Class A)のコンストラクタをどうするのか
という問題もあり、実現できそうにありません。
どのように実現することが一番好ましいでしょうか?
(今までのとおり、そのまま3つのメソッドは書いたほうがいいのか・・・)
よろしくお願いします。
#追記
環境はVC++ 2008 EEです。

Re:シングルトンクラスのテンプレート化
Posted: 2009年12月29日(火) 22:56
by Justy
一番手っ取り早そうなのは
[color=#d0d0ff" face="monospace]
template <typename P1>
static bool GetInstance(P1 p1)
{
if (m_Instance == NULL)
{
m_Instance = new T(p1);
return true;
}
else
return false;
}
template <typename P1, typename P2>
static bool GetInstance(P1 p1, P2 p2)
{
if (m_Instance == NULL)
{
m_Instance = new T(p1, p2);
return true;
}
else
return false;
}
template <typename P1, typename P2, typename P3>
static bool GetInstance(P1 p1, P2 p2, P3 p3)
{
if (m_Instance == NULL)
{
m_Instance = new T(p1, p2, p3);
return true;
}
else
return false;
}
[/color]
とかをメンバに加えるとか。
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 00:04
by Poco
Game Programming Gemsにあった、シングルトンのテンプレート版の
ソースを載せておきます。
template< typename T >
class Singleton
{
public:
Singleton()
{
assert( ! singleton_ );
int offset = (int)(T*)1 - (int)(Singleton<T>*)(T*)1;
singleton_ = (T*)((int)this + offset);
}
~Singleton()
{
assert( singleton_ );
singleton_ = 0;
}
static T& getInstance(void)
{
assert( singleton_ );
return *singleton_;
}
private:
static T * singleton_;
};
template< typename T > T* Singleton<T>::singleton_ = 0;
後は、
class A : public Singleton<A>{};
として、派生クラスAに好きなコンストラクタを定義できるようになると思います。
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 00:13
by たかぎ
> ぽこさん
これだと、コピーコンストラクタを殺していないので、シングルトンを保証できませんね。
あと、コンストラクタでやっているオフセット計算も変で、こんなことをしなくても、普通にダウンキャストするだけでよいと思うのですが...
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 00:23
by kazuoni
ご回答ありがとうございます。
すみません。。テンプレート化というと、そちらもあるんですね。。
自分がやろうとしていたのはJustyさんの方ではなく、
ぽこさんの提示してくださったような、テンプレートでした。
ソースコードまで挙げていただいたのに、大変申し訳ありませんでした。
実際、自分のものにぽこさんのあげていただいたものをどのように組み込んだらいいかよくわかりません。
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 01:18
by Poco
たかぎさん:
指摘ありがとうございます。
指摘された点を修正したものと、動作確認プログラムを載せます。
#include <iostream>
#include <cassert>
template< typename T >
class Singleton
{
public:
Singleton()
{
assert( ! singleton_ );
singleton_ = reinterpret_cast< T* > (this);
//singleton_ = dynamic_cast< T* > (this); // dynamic_castだと直下のアサーションに引っかかる。Why?
assert( singleton_ );
}
virtual ~Singleton()
{
assert( singleton_ );
singleton_ = 0;
}
static T& getInstance(void)
{
assert( singleton_ );
return *singleton_;
}
private:
static T * singleton_;
Singleton( const Singleton& s ); // コピーコンストラクタは呼び出し禁止
};
template< typename T > T* Singleton<T>::singleton_ = 0;
//////動作確認用のクラス
class A : public Singleton<A>
{
public:
A(){}
void test() {
std::cout << "It's test" << std::endl;
}
};
class B : public Singleton<B>
{
public:
B(){}
};
////// シングルトンオブジェクト作成
A a;
// A a2; // NG:Singleton<A>は2つ生成できない
B b;
int main()
{
// A a2(a); // NG:コピーコンストラクタは呼び出せない
// B b2 = b; // NG:コピーコンストラクタは呼び出せない
A& a3 = A::getInstance();
a3.test();
return 0;
}
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 01:18
by Justy
gemsのこのシングルトンクラスはインスタンスの生成と破棄を別管理として
アクセスの為だけに存在するわけですね。
□ たかぎさん
>こんなことをしなくても、普通にダウンキャストするだけでよいと思うのですが
gemsによるとこのシングルトンクラスを別のクラスと合わせて多重継承した際に
シングルトンクラスの thisと派生したクラス(T)の thisが異なることについて言及しています。
その対策の為らしいのですが、ダウンキャストで何故ダメなのかはよくわかりません……。
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 01:37
by たかぎ
> その対策の為らしいのですが、ダウンキャストで何故ダメなのかはよくわかりません……。
意味不明ですね。
Re:シングルトンクラスのテンプレート化
Posted: 2009年12月30日(水) 10:34
by kazuoni
ご回答ありがとうございます!
ぽこさんの提示していただいたソースコードをちょっと変えるだけで
自分のやりたいことが実現できました。
ダウンキャストなんて頭の片隅ぐらいにしかなかったので、
見直す機会になり、大変参考になりました。
ありがとうございました。
次回もよろしくお願いします。