0

2つのシングルトンがあります。最初のヘッダーは次のようになります(シングルトンパターンに関係のないものはすべて省略しました)。

#ifndef TEXTUREMANAGER_DEFINED_H
#define TEXTUREMANAGER_DEFINED_H
class FontManager;
class TextureManager
{
private:
    static TextureManager *instance;
    TextureManager();
public:
    FontManager *fontManager;
    static TextureManager* Instance();
};

#endif

そして、実装では、これはInstance()メソッド(およびインスタンスの静的メンバーの初期化)です。

#include "FontManager.h"
TextureManager * TextureManager::instance = 0;
TextureManager* TextureManager::Instance ()
{
    if (instance==0)
        instance=new TextureManager;
    return instance;
}

そしてこれはコンストラクターです:

TextureManager::TextureManager()
{
    fontManager=FontManager::Instance();
}

2番目のシングルトン(FontManager)の設計はまったく同じですが、FontManagerポインターの代わりにTextureManagerポインターがあり、そのコンストラクターでTextureManager :: Instance()を使用してそのポインターを初期化します。これは次のように機能するはずです。TextureManagerが最初にインスタンス化され(プログラムの起動時)、そのコンストラクターでFontManagerシングルトンがFontManager :: Instance()を初めてインスタンス化します。FontManagerは、そのコンストラクターで、TextureManager :: Instance()を使用してそのポインターをTextureManagerに割り当て、このメソッドは、既に存在するTextureManagerインスタンスを返します。右?

しかし、その代わりに、Instance()メソッドが常に新しいインスタンスを作成するため、プログラムは無限ループに入ります(理由はわかりません)。私はif (instance==0)いつも真と評価されるのが好きではありません。

4

2 に答える 2

7

のコンストラクターがそのコンストラクターを呼び出し、次にそのコンストラクターが....のコンストラクターをTextureManager呼び出す無限ループを作成したためです。FontManagerTextureManager

静的変数が割り当てられる前にコンストラクターが完了する必要があるため、このループに陥ります。

于 2012-04-05T09:14:03.653 に答える
0

シングルトンの場合、コンストラクターをパブリックインターフェイスとして公開しません。代わりに、個別の静的インスタンス取得メンバー関数とプライベートコンストラクターがあります。

class Foo
{
    Foo() { /* ... */ }
public:
    static Foo & get()
    {
        static Foo instance;   // uses private constructor
        return instance;
    }
};

静的メンバーの代わりに、ポインタートリックを実行することもできますがstatic std::unique_ptr<Foo>、プログラムの最後で適切に破棄するためのが必要です。

于 2012-04-05T09:19:35.370 に答える