オブジェクトがそれ自体を削除しても問題はありません。コレクションからウィンドウを削除してから削除するようにウィンドウマネージャーに指示するだけです。ウィンドウマネージャにウィンドウオブジェクトを削除させる場合、それはさらに良いことです。
この動作を本当に避けたい場合は、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;
};