シングルトンクラスのテンプレート化

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kazuoni

シングルトンクラスのテンプレート化

#1

投稿記事 by kazuoni » 15年前

お邪魔します。

現在、シングルトンクラスのテンプレート化で悩んでいます。
今自分は添付ファイルSingleton.txtのようにシングルトンクラスを管理しています。

ただ、シングルトンクラスのたびに
GetInstance
DeleteInstance
Order
メソッドを定義しなければいけないので、
これを今の呼び出し方と同様かつ、上記の関数をテンプレート化できないかと考えています。

個人的には、添付ファイルVirtualClass.txt
のような感じでテンプレートクラスを用意し、
シングルトンクラスにしたいクラスを
このTemplateForSingletonクラスから派生させることができたら
なんて思っていますが、このままだと派生クラス(Class A)のコンストラクタをどうするのか
という問題もあり、実現できそうにありません。

どのように実現することが一番好ましいでしょうか?
(今までのとおり、そのまま3つのメソッドは書いたほうがいいのか・・・)

よろしくお願いします。

#追記
環境はVC++ 2008 EEです。 画像

Justy

Re:シングルトンクラスのテンプレート化

#2

投稿記事 by Justy » 15年前

 一番手っ取り早そうなのは
[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]

とかをメンバに加えるとか。

Poco

Re:シングルトンクラスのテンプレート化

#3

投稿記事 by Poco » 15年前

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:シングルトンクラスのテンプレート化

#4

投稿記事 by たかぎ » 15年前

> ぽこさん
これだと、コピーコンストラクタを殺していないので、シングルトンを保証できませんね。
あと、コンストラクタでやっているオフセット計算も変で、こんなことをしなくても、普通にダウンキャストするだけでよいと思うのですが...

kazuoni

Re:シングルトンクラスのテンプレート化

#5

投稿記事 by kazuoni » 15年前

ご回答ありがとうございます。

すみません。。テンプレート化というと、そちらもあるんですね。。
自分がやろうとしていたのはJustyさんの方ではなく、
ぽこさんの提示してくださったような、テンプレートでした。
ソースコードまで挙げていただいたのに、大変申し訳ありませんでした。

実際、自分のものにぽこさんのあげていただいたものをどのように組み込んだらいいかよくわかりません。

Poco

Re:シングルトンクラスのテンプレート化

#6

投稿記事 by Poco » 15年前

たかぎさん:

指摘ありがとうございます。
指摘された点を修正したものと、動作確認プログラムを載せます。
#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;
}

Justy

Re:シングルトンクラスのテンプレート化

#7

投稿記事 by Justy » 15年前

 gemsのこのシングルトンクラスはインスタンスの生成と破棄を別管理として
アクセスの為だけに存在するわけですね。


□ たかぎさん
>こんなことをしなくても、普通にダウンキャストするだけでよいと思うのですが

 gemsによるとこのシングルトンクラスを別のクラスと合わせて多重継承した際に
シングルトンクラスの thisと派生したクラス(T)の thisが異なることについて言及しています。

 その対策の為らしいのですが、ダウンキャストで何故ダメなのかはよくわかりません……。

たかぎ

Re:シングルトンクラスのテンプレート化

#8

投稿記事 by たかぎ » 15年前

>  その対策の為らしいのですが、ダウンキャストで何故ダメなのかはよくわかりません……。

意味不明ですね。

kazuoni

Re:シングルトンクラスのテンプレート化

#9

投稿記事 by kazuoni » 15年前

ご回答ありがとうございます!

ぽこさんの提示していただいたソースコードをちょっと変えるだけで
自分のやりたいことが実現できました。
ダウンキャストなんて頭の片隅ぐらいにしかなかったので、
見直す機会になり、大変参考になりました。
ありがとうございました。

次回もよろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る