これらのリストにアクセスするのは得策ではないかもしれませんが、この種のアクセスが必要な場合は、さまざまな方法でアクセスできます。グローバル変数による最も簡単な方法は次のとおりです。
// forward declare Game_object:
class Game_object;
// Declare lists:
typedef std::list <Game_object *> ListObjects;
typedef std::list <Explosion *> ListExplosions;
ListObjects Objects;
ListExplosions Explosions;
class Game_object
{
public:
void Update()
{
// Update Objects...
for (ListObjects::const_iterator O = Objects.begin(); O != Objects.end(); ++O)
{ ... };
// Update Explosions...
for (ListExplosions::const_iterator E = Explosions.begin(); E != Explosions.end(); ++E)
{ ... };
};
void Render()
{
// Render Objects...
for (ListObjects::const_iterator O = Objects.begin(); O != Objects.end(); ++O)
{ ... };
// Render Explosions...
for (ListExplosions::const_iterator E = Explosions.begin(); E != Explosions.end(); ++E)
{ ... };
};
//Other stuff
};
それは良い考えではありません.グローバル変数は面倒であり、他のクラスがアクセスしてその内容を変更する可能性のあるグローバルリストでは、別のクラスが同時に内容を変更しようとするとさらに悪化する可能性があります. ただし、スレッドを使用していない場合は、それほど面倒ではありません。
他のアプローチは、マネージャーを作成することです。管理者はリストの所有者である必要があり、メソッド、、およびメソッドがSetters
必要Getters
ですDeleters
。リストの内容を更新するには、マネージャーへの参照をレンダラー/アップデーターに渡し、マネージャーからリストへの参照を取得します。
class ObjectManager
{
public:
typedef std::list <Game_object *> ListObjects;
void AddObject(const ObjectStuff &os)
{ ... };
const ListObjects &GetObjects()
{ return Objects; };
private:
ListObjects Objects;
}
class ExplosionManager
{
public:
typedef std::list <Explosion *> ListExplosions;
void AddExplosion(const ExplosionStuff &es);
{ ... };
const ListExplosions &GetExplosions()
{ return Explosions; };
private:
ListExplosions Explosions;
}
void Render(const ObjectManager &om)
{
// Ask ObjectManager for the object list
}
void Render(const ExplosionManager &em)
{
// Ask ExplosionManager the explosion list
}
上記のコードは単純で非常に単純な概算ですが、例としてのみ使用しています。上記のアプローチの利点は、リストが所有者オブジェクトによってのみ変更されることです。リストがマネージャーから必要な場合は読み取り専用の方法で提供され、スレッドを使用している場合は、ロックを追加するのが非常に簡単です。リストの使用中の変更を避けるために、マネージャ メソッドでロックを解除します。
これは尋ねられませんが、言う価値があると思います: オブジェクト ポインターをコンテナーに格納することを避け、オブジェクト インスタンスごとにストア タイプを変更することをお勧めします。
std::list <Game_object *> VS std::list <Game_object>
ポインターを使用している場合は、オブジェクトの割り当てと割り当て解除を処理する必要があります。リストがグローバルClose
である場合、リストが所有されている場合、リストに格納されているポインターによって管理されるすべてのメモリの割り当てを解除するパブリック メソッドが必要です。オブジェクトによって、同じプロセスをオブジェクト デストラクタに実行する必要があります。
ただし、オブジェクト インスタンスを格納している場合、リスト デストラクタは、有効期間が終了したときに格納されているすべてのオブジェクトの割り当てを解除します。コードはよりクリーンで維持しやすくなります。