也许访问这些列表不是一个好主意,但是如果您需要这种访问权限,您可以通过多种方式来实现,最简单的是全局变量:
// 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
方法来解除分配由存储在列表中的指针管理的所有内存,如果列表是拥有的通过某些对象,您需要对对象析构函数执行相同的过程。
但是,如果您要存储对象实例,则列表析构函数会在其生命周期结束时释放所有存储的对象,代码更清晰且更易于维护。