2

シングルトン テンプレートを使用して複数のオブジェクトを作成する方法があるという点で、シングルトン テンプレートは実際にはシングルトンではない可能性があると言われました。修理方法を尋ねたところ、無視されました。そのため、私のシングルトン テンプレート クラスは本当にシングルトンなのでしょうか?

#ifndef SINGLETON_H_
#define SINGLETON_H_

template <class T>
class Singleton
{
private:
static T* instance;

protected:
    Singleton<T>(  )
    {
    }

public:
    static T* getInstancePtr(  )
    {
        if ( instance == 0 )
            instance = new T(  );

        return instance;
    }
};

template <class T> T* Singleton<T>::instance = 0;

#endif

これは、次のようにシングルトンにしたいクラスに継承されます:-

class Console : public Singleton< Console >
{
};
4

6 に答える 6

4

デフォルトのコンストラクターを作成しましたprotected。派生クラスはそれにアクセスできるため、これはコンパイルされます。

Console c1, c2;
于 2012-06-29T19:26:35.907 に答える
3

シングルトンであることを保証できない単純な理由の 1 つは、スレッド セーフが原因です。

2 つ以上のスレッドが同時に getInstancePtr を呼び出すと、スレッドのスワッピングによっては 2 つ以上のインスタンスが作成される場合があります。

于 2012-06-29T19:25:26.113 に答える
2

シングルトン パターンを実装するには、ローカルの静的変数を使用します。

template <class T>
class Singleton
{
    static T* getInstancePtr(  )
    {
        static T instance; // <-- HERE

        return &instance;
    }
};

コードがはるかに少ないだけでなく、スレッドセーフも保証されています。への最初の呼び出しで構築され、Singleton<X>::getInstancePtr()後続の呼び出しで 1 つのインスタンスが取得されます。

または、スレッドごとに 1 つのインスタンスが必要な場合は、thread_local代わりに次を使用できます。

template <class T>
class Singleton
{
    static T* getInstancePtr(  )
    {
        thread_local T instance; // <-- HERE

        return &instance;
    }
};
于 2013-05-12T07:47:02.047 に答える
0

マルチスレッド環境で作業するには、別のソリューションが必要です。複数のスレッドが存在する場合にオブジェクトのインスタンスが 1 つだけ作成されるようにするには、特定の言語機能を使用する必要があります。より一般的な解決策の 1 つは、Double-Check Locking イディオムを使用して、別々のスレッドがシングルトンの新しいインスタンスを同時に作成しないようにすることです。

于 2012-06-29T19:27:46.413 に答える
0

マルチスレッドの問題以外に、2 つのインスタンスを作成できる場合がありました。以下のクラスコンソールを初期化することにより

class Console : public Singleton< Console >
{
};

そのようです

Console c1;

Console の 2 つのインスタンスができてしまいました。1 つは Singleton クラス内に保持されているインスタンス ポインター内にあり、もう 1 つは c1 オブジェクト自体内にあります。Singleton クラスを次のように変更することでこれを解決しました。

#ifndef SINGLETON_H_
#define SINGLETON_H_

template <class T>
class Singleton
{
private:
    static T* instance;

protected:
    Singleton<T>(  )
    {
        if ( instance == 0 )
            instance = static_cast<T*>(this);
    }

public:
    static T* getInstancePtr(  )
    {
        return instance;
    }
};

template <class T> T* Singleton<T>::instance = 0;

#endif

ただし、マルチスレッドの問題以外は、Singleton クラスが複数のインスタンスになる可能性が低くなることがより確実になりました。

于 2012-06-29T20:26:50.073 に答える