我有一個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;
}
}
存儲'std :: shared_ptr'將意味着類型不需要公共基類或虛擬析構函數 –
@JonathanWakely雖然沒有共享,但會有點濫用。嚴重的是,沒有多態的UI是瘋狂的。如果沒有虛擬方法來繪製和響應點擊,至少,程序組織有一些非常錯誤的地方。 – Potatoswatter
正如我在我的問題中所述,我所有的UI對象都是從一個共同的父對象繼承而來的(在這裏沒有任何問題:-)。我試圖創建一個這樣的地圖,但沒想到使用unique_ptr。唯一的缺點是unique_ptr是一個C++ 11項目,我們還沒有完全接受。 – Watusimoto