我正在用c ++创建一个二维世界,其中充满了类似动物的实体,我正在编写一个程序。我有一个世界级和实体类(以及从实体继承的一系列不同类型的实体)。
我希望实体“知道”其中的哪个世界并且能够与2d实体数组良好地交互,但我不希望它继承世界(毕竟,实体不是世界)。所以我只想尝试一些好的方法来实现它。我当然可以让每个实体包含一个指向它所在世界的指针,但它看起来相当混乱。是否有更简单的方法让二维数组中的实体“知道”哪个世界对象包含它。
在c ++中有没有办法让一个对象成为另一个对象的成员变量来知道包含它的对象?
谢谢!
答案 0 :(得分:3)
聚合(为每个实体提供世界指针)是最简单的解决方案。另一个解决方案是拥有第三个mediator object,它保持指向世界和实体的指针,存储它们之间的关系,并调解它们之间的通信(因此也就是名称)。这个对象可能是一个全局单例(大多数程序员会不寒而栗,但我不认为其中一些是坏事),否则每个世界和实体都需要一个指向 it 的指针来进行通信,这显然不是第一个解决方案的重大改进。
答案 1 :(得分:1)
哦,亲爱的。我有一个世界级的
除此之外,您的实体与其环境的有意义的互动是什么?如果它能够查询任意信息,请查看地平线,询问其他实体的状态吗?
或者根据其位置和属性,是否应该有一些有限的视图?
在第一种情况下,它显然是一个像神似的实体,并且诸如封装和分离关注等世俗问题不适用。
在第二种情况下,公开一个接口(你可以将它设计为抽象以减少耦合),这样它就可以只看到它应该的东西。
好的,所以第二种情况看起来像
class World; // is a dumb container of entities
class Environment; // is an entity's window on the world
class Entity {
public:
void take_a_turn(Environment&) = 0;
};
class Environment {
public: // control what an entity can do to (see of) the World
container<const Entity*> visible_entities() const;
result attempt_to_eat(const Entity*);
result attempt_to_mate(const Entity*);
result run_away_from(const Entity*);
};
当然,如果您的Entity对象活动(即,它们在自己的线程中自主且连续地运行),则需要保持引用或指向世界或环境。
但是,如果您只是一次调用它们,当它们有机会做某事时,每次都可以传递引用。
答案 2 :(得分:1)
假设我已经正确地理解了你,每个实体中世界指针的替代方法是给每个世界一个唯一的id,然后将该id存储在实体中,因为它被添加到它的世界中。
答案 3 :(得分:0)
对于世界而言,也许你可以创造某种全球引擎。引擎将具有系统,并且世界可被视为引擎内的系统。您可以从引擎请求实体构造函数中的world系统,并在那里执行您需要的操作。
class World : public System
{
// info in here
}
class Engine
{
public:
World * getWorldSystem(); // Not as good
System * getSystem( std::string name ); // uses lookup, convert to right type
}
引擎类的问题是“我如何引用它?”在大多数情况下,您将包含引擎的.h文件,该文件也包含:
extern Engine * ENGINE;
在它内部,这是我理解的可怕,但是使用引擎/系统架构,你必须把它放在某个地方。或者你明确地使用单身。
至于你的继承树可能会完全改变你的设计方案。基于组件的体系结构可能是解决此问题的一种方法。
虽然继承在很多情况下都有意义,但构建基于组件的实体可以帮助您处理每种动物必须具有的巨大链条。
采取:
class Component
{
public:
Component();
virtual ~Component();
}
class WalkComponent : public Component
{
public:
Walk(); // Something here allows the entity to walk on the ground
}
class FlightComponent : public Component
{
public:
Fly(); // Something in here moves the entity around using flight
}
你可以看到你可以将一个步行组件和一个飞行组件附加到实体上,它可以同时使用两者,而不是试图创建一个允许这两者的继承树。