我有一个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),它使您可以以一致的方式将实例化的接口(interface)映射到其类型。
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;
   }
}

最佳答案

当前,您仅为每种类型的一个UI元素分配了存储空间。从根本上来说,要保持该原理并拥有任意数量的窗口是不可能的。

快速而肮脏的解决方案是为窗口编号添加模板参数。如果是游戏,并且只有有限数量的玩家,则可以为某些预定数量的窗口提供静态存储。

template <typename T, int N>
T *getUI()

但是,将UI身份绑定(bind)到类型系统的方法从根本上来说是有缺陷的,我建议使用多态性和容器的更常规方法。

一种通过类型识别对象并动态存储对象的方法看起来像
class UIManager {
    std::map< std::type_index, std::unique_ptr< UIBase > > elements;

    template< typename T >
    T & GetUI() { // Return reference because null is not an option.
        auto & p = elements[ typeid( T ) ];
        if ( ! p ) p.reset( new T );
        return dynamic_cast< T & >( * p );
    }
}

请注意,这要求UIBase具有虚拟析构函数,否则退出时对象将无法正确终止。

关于c++ - 模板和延迟初始化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18730073/

10-13 08:20