也许是访问这些列表没有好主意,但如果你需要这种存取权限,你可以通过多种方式,全局变量最简单的做到这一点:
// 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
方法来解除分配列表中存储的指针所管理的所有内存,如果列表属于一些对象,你需要在对象析构函数中执行相同的过程。
但是,如果您要存储对象实例,那么列表析构函数将释放所有存储的对象,这些对象在其生命周期结束时会取消分配,代码更清晰且更易于维护。
根据我的经验,对这个问题的更好的解决方案是让这些类*不需要通过移动其他地方需要的逻辑来访问这些列表。 – molbdnilo
我必须同意molbdnilo在这里,搞乱前面的声明和extern会导致难以维护,相互依赖的意大利面代码。最好的方法是重新设计你在做什么。 –