単一の UI クラスから継承する一連のクラスを管理する UIManager があります。現在、個々の UI が遅延して初期化され、静的に保存される次のように動作します。
class UIManager
{
public:
UIManager(); // Constructor
virtual ~UIManager(); // Destructor
template <typename T>
T *getUI()
{
static T ui(); // Constructs T, stores result in ui when
// getUI<T>() is first called
return &ui;
}
}
呼び出し:
getUI<NameEntryUI>()->activate();
また
getUI<MenuUI>()->render();
複数のプレイヤー、つまり複数のゲーム ウィンドウ、つまり複数の UIManager を使用できるようにする設計変更を検討しています。UIManager が削除されたときに、構築されたすべての ui オブジェクトをクリーンアップする必要があります (現在、ui オブジェクトは静的であるため、プログラムが終了するまで残ります)。
UIManagerが強制終了されたときにUIオブジェクトを削除するために上記を書き直すにはどうすればよいですか?
======================================
これが私が実装した解決策です。初期の結果は、うまく機能しているということです。
基本的に、私は Potatoswatter によって提案されたアイデアから始めました。これは、typeid(T) について知らなかったために開始した後に中止したアプローチに似ていたため、気に入りました。C++98 機能のみを使用するようにコードをバックポートしました。全体の鍵となるのは typeid(T) です。これにより、インスタンス化されたインターフェイスを一貫した方法でその型にマップできます。
class UIManager
{
typedef map<const char *, UserInterface *> UiMapType;
typedef UiMapType::iterator UiIterator;
map<const char *, UserInterface *> mUis;
public:
UIManager(); // Constructor
virtual ~UIManager() // Destructor
{
// Clear out mUis
for(UiIterator it = mUis.begin(); it != mUis.end(); it++)
delete it->second;
mUis.clear();
}
template <typename T>
T *getUI()
{
static const char *type = typeid(T).name();
T *ui = static_cast<T *>(mUis[type]);
if(!ui)
ui = new T();
mUis[type] = ui;
return ui;
}
}