Appearance
第08回 画像リソースの管理
2 / 4 画像ハンドルの所有と解放を確認する
このステップの目的
画像ハンドルの寿命をImageManagerへ集約し、解放漏れと二重解放を防ぐ
Managerが所有する
LoadGraph()が返すハンドルは、ゲームの実行中に画像を使うための値です。 ImageManagerはハンドルを配列へ保存し、ゲーム中の描画へ提供します。
Entityがハンドルを所有しないため、PlayerやEnemyの破棄順を画像の解放順と結び付けずに済みます。
ハンドルをIDの並びと対応する配列へ保存し、まだ読み込んでいない要素は-1として扱います。
ImageManager.h / ImageManager.cppcpp
std::array<int, static_cast<std::size_t>(Id::Count)> handles = {};
ImageManager(const ImageManager&) = delete;
ImageManager& operator=(const ImageManager&) = delete;
ImageManager::ImageManager()
{
handles.fill(-1);
}デストラクタで解放する
Managerが破棄されるとき、取得済みのハンドルをDeleteGraph()で解放します。 読み込み途中で失敗しても、未取得を表す-1を確認してから解放します。
ImageManager.cppcpp
for (int handle : handles)
{
if (handle != -1)
DeleteGraph(handle);
}コピーを禁止する宣言も、同じハンドルを2つのManagerが所有しないために必要です。
このように、取得した資源を所有者の生成・破棄の流れへ結び付けて管理する考え方をRAIIと呼びます。 ここでは用語を暗記するのではなく、「ImageManagerが取得し、ImageManagerが解放する」という対応を確認します。
チェックリスト
- 画像ハンドルの所有者が
ImageManagerである - デストラクタで取得済みハンドルを解放している
- 所有クラスのコピーを禁止する理由を説明できる