Skip to content
第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である
  • デストラクタで取得済みハンドルを解放している
  • 所有クラスのコピーを禁止する理由を説明できる