移動関数が呼び出されたときに、他のヘビや食べ物の場所を見つける機能が必要なだけです。初期化時にそれらの存在を知る必要はありません!
したがって、ヘビのコレクションと食品のコレクションを作成し、これらのコレクションへの参照を新しく作成されたヘビと食品に渡すことができます。最初にそれらのコレクションを作成するだけです。
おそらく、ファクトリとしても機能する別のクラスを介してこれを行うことができます。
class GameManager;
class Snake
{
friend class GameManager;
public:
int getX() { return _x; }
int getY() { return _y; }
void setPosition(int x, y) { /* ... */ }
private:
Snake(GameManager* manager, int x, int y) : _manager(manager), _x(x), _y(y) {}
GameManager* _manager;
int _x, _y;
};
class GameManager
{
public:
const std::vector<Snake*>& Snakes() { return _snakes; }
Snake* SpawnSnake(int x, int y)
{
Snake* newSnake = new Snake(this, x, y);
snakes.push_back(newSnake);
return snake;
}
private:
std::vector<Snake*> _snakes;
};
(ほんの一例です。コードは実際にコンパイルされるかどうかテストされていません。E&OE)
コンストラクターがプライベートであるため、作成されたすべてのGameManager
スネークがスネーク ベクトルで見つかることが保証されます。各スネークは、ゲーム内の他のすべてのスネークを含むベクターを取得するためにSnake
呼び出すことができ、その後、それらの位置を個別に照会できます。_manager.Snakes()
これは、食品もサポートするように簡単に一般化できます。
これには、新しいオブジェクトを取得したときに実際に使用する準備ができていることを保証するという点で、他の回答で提案されている「construct-initialise」パターンよりも小さな利点がありSnake
ます...この例は完全なRAIIではありませんが、合理的に例外安全にするための最小限の努力。