我有一个 UIManager 管理从单个 UI 类继承的一系列类。目前,它的工作原理是这样的,其中各个 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;
}
}