1

私はC++で、ゲームで使用するための一種の単純な「ウィンドウ」システムをプログラムしようとしています。これは、ゲーム領域(ゲーム自体のグラフィックスの内部、つまり、 OSのGUIウィンドウ)。ウィンドウオブジェクト(ここでは「クラスウィンドウ」と呼びます)には、キーを押すなどのイベント用のメソッドと、そのイベントの受信時に呼び出されるハンドラーをフックする機能があります。

ウィンドウは「ウィンドウマネージャー」に収集されます(または収集されます)。ウィンドウオブジェクトには、親ウィンドウマネージャーのウィンドウ削除ルーチンを呼び出してそれ自体を削除する「close()」メンバーが含まれます。たとえば、ウィンドウのボタンにフックされたイベントハンドラーは、このルーチンを呼び出してウィンドウを閉じる場合があります(「OK」ボックスを考えてください)。

問題は、これが「delete *this;」のように聞こえるということです。私が聞いたは、ノーノーです。確かに、それは直接は行いませんが、効果は同じです。オブジェクトには、それ自体の破棄をもたらすメンバー関数(たとえば、「close()」関数、またはハンドラーをトリガーして「close()」関数が呼び出されています。)これが悪い場合、これを設計するためのより良い方法は何ですか?

4

1 に答える 1

4

オブジェクトがそれ自体を削除しても問題はありません。コレクションからウィンドウを削除してから削除するようにウィンドウマネージャーに指示するだけです。ウィンドウマネージャにウィンドウオブジェクトを削除させる場合、それはさらに良いことです。

この動作を本当に避けたい場合は、bool dead;に初期化する各ウィンドウにを追加できますfalse。ウィンドウを閉じるときは、を設定しthis->dead = true;ます。フレームごとに、ウィンドウマネージャーにウィンドウを繰り返し処理させ、無効になっているウィンドウを削除します。

このソリューションでは、削除されたウィンドウへの参照を持つ外部システムから発生するエラーは修正されませんが、ウィンドウの削除を一元化できるという利点があることに注意してください。

私は多くのゲームのウィンドウシステムを設計しましたが、私の経験では、ウィンドウが自分自身を削除できるようにすることは、エラーが発生しやすい場合でも、非常に洗練されたソリューションです。

最小限の例:

class Window
{
  public:
    void keyPressCallback(int c)
    {
      if (c == KEY_ESC)
      {
        manager.destroy(this);
        return;
      }
    }
    WindowManager& manager;
};

class WindowManager
{
  public:
    void destroy(Window* target)
    {
      delete target;
      windows.erase(std::find(windows.begin(), windows.end(), target));
    }
    std::vector<Window*> windows;
};

そのウィンドウへのポインタが残っていない限り、このメソッドは完全に安全で意味的に正常です。ウィンドウが閉じる信号を受信すると、ウィンドウは自動的に閉じます。

deadフラグを使用した同じ例:

class Window
{
  public:
    Window() : dead(false) {}
    void keyPressCallback(int c)
    {
      if (c == KEY_ESC)
      {
        dead = true;
        return;
      }
    }
    bool dead;
};

class WindowManager
{
  public:
    void cleanup()
    {
      for (auto iter = windows.begin(); iter != windows.end(); ++iter)
      {
        if (iter->dead) windows.erase(iter);
      }
    }
    std::vector<Window*> windows;
};
于 2013-03-24T06:46:29.717 に答える