Skip to content

第11回 参照・ポインタ・寿命

前回: 第10回 音と演出 / 次回: 第12回 独自要素の追加

今回の授業内容

  • 完成に近づいたコードの所有関係を整理する
  • 値渡しと参照渡しの違いを確認する
  • const参照を使う理由を説明する
  • 不要なポインタや不要なnullptrチェックを増やさない設計を確認する
  • 第12回の拡張に向けて、安全に変更できる場所を見つける

今回の開始状態

第10回終了時点では、ゲームとして必要な主要機能がそろっています。
今回の終了時点では、新機能を大きく増やさず、コードの受け渡しと寿命を点検します。

この回は「完成版を読む」回ではありません。
自分がここまで実装したコードを対象に、どのオブジェクトを誰が持っているかを整理する回です。

変更するファイル

ファイル変更内容
Player.h / Bullet.h / Enemy.hDraw()などの引数が適切か確認する
Game.h所有しているメンバ変数を確認する
Game.cpp参照で渡すべき箇所、値で十分な箇所を確認する

所有しているものを確認する

Gameは、ゲーム全体で存在し続けるものを所有します。

cpp
Player player;
ImageManager images;
SoundManager sounds;
std::array<Bullet, maxBullets> bullets = {};
std::array<Enemy, maxEnemies> enemies = {};
std::array<Effect, maxEffects> effects = {};

PlayerBulletは、画像管理を所有しません。
描画に必要な間だけ、Gameから借りて使います。

const参照で借りて使う

画像管理はコピーするものではありません。
描画時に中身を書き換える必要もないため、const参照で受け取ります。

cpp
void Player::Draw(const ImageManager& images) const;

この形にすると、呼び出された側はimagesを読み取り専用で使うことが明確になります。

不要なポインタを増やさない

このプロジェクトでは、主要なオブジェクトはGameが直接所有しています。
そのため、所有関係が明確なものを無理にポインタへ変える必要はありません。

避けたい例は、理由なく次のようにすることです。

cpp
Player* player = nullptr;

nullptrになり得る設計でないなら、ポインタにする必要はありません。
不安だから確認するのではなく、誰が所有し、いつまで存在するかを設計で決めます。

DXライブラリのハンドルのように、読み込み失敗時の値が-1と決まっているものは確認します。
これは不要な防御ではなく、素材がない状態でも動かすための仕様です。

実習

  1. Gameが所有しているメンバ変数を書き出す
  2. 各クラスが関数の引数として借りているものを書き出す
  3. Draw()の引数がconst参照になっているか確認する
  4. 値渡しに変更すると何が起きるかを説明する
  5. 不要なポインタや不要なnullptrチェックを追加していないか確認する

今回の完成条件

  • 所有と利用の違いを説明できる
  • const参照を使う理由を説明できる
  • 不要なポインタを増やさない判断ができる
  • 自分のコードの所有関係を表で説明できる

まとめ

今回は、完成に近づいたコードを安全に扱うため、所有、参照、寿命を整理しました。
次回は、この構造を崩さない範囲で独自要素を追加します。