0

我一直在网上搜索,我似乎没有找到任何替代方法来比较两个多态对象是否是同一类型,或者多态对象是否是一种类型。这样做的原因是因为我要在我目前正在创建的游戏中实现一个实体系统。

除了使用宏或演员表(演员表不是这样做的可移植方法)之外,我还没有找到另一种方法。目前这就是我识别对象的方式,有没有更有效或更有效的方法来做到这一点?(不使用 C++ RTTI)

我把它贴在了 pastebin 上,因为把它贴在这里太麻烦了。 http://pastebin.com/2uwrb4y2

如果你仍然不明白我想要达到的目标,我会试着解释一下。游戏中的实体就像游戏内部的对象(例如玩家或敌人),它具有附加到它的组件,这些组件是实体的数据。实体系统中的系统是将游戏的数据和逻辑结合在一起的系统。

例如,如果我想在屏幕上显示一个模型,它将类似于:

World world; // Where all entities are contained

// create an entity from the world, and add
// some geometry that is loaded from a file
Entity* e = world.createEntity();
e->add(new GeometryComponent());
e->get<GeometryComponent>()->loadModel("my_model.obj"); // this is what I want to be able to do


world.addSystem(new RenderingSystem());

// game loop
bool isRunning = true;
while(isRunning) 
{
   pollInput();
   // etc...      

   // update the world
   world.update();
}

编辑:这是一个用 Java 编程的框架,主要完成我想做的事情。 http://gamadu.com/artemis/tutorial.html

4

3 回答 3

3

std::is_polymorphic。我相信boost也有。

如果 T 是多态类(即声明或继承至少一个虚函数的类),则提供等于 true 的成员常量值。对于任何其他类型,值为 false。

http://en.cppreference.com/w/cpp/types/is_polymorphic


编辑:

为什么你不能在你的例子中这样做?

Entity* e = world.createEntity();
GemoetryComponent* gc = new GeometryComponent();
gc->loadModel("my_model.obj");
e->add(gc);

在剥离类型信息之前创建结构。

于 2012-11-03T03:26:20.283 回答
0

如果您决定不使用 C++ 的内置 RTTI,您可以通过从包含虚拟方法的基类派生所有类来自己重新实现它:

class Base {
public:
    virtual string getType() = 0;
};

然后每个派生类都需要使用返回不同字符串的版本重载此方法:

class Foo : public Base {
public:
    string getType() { return "Foo"; }
};

然后,您可以简单地比较调用getType()每个对象的结果,以确定它们是否为同一类型。string如果您预先知道将要创建的所有派生类,则可以使用枚举而不是 a 。

于 2012-11-03T04:43:29.577 回答
0
Entity* e = world.createEntity();
e->add(new GeometryComponent());
e->get<GeometryComponent>()->loadModel("my_model.obj"); 
   // this is what I want to be able to do

首先很简单:所有可以添加的组件都有一个基本类型,否则您将无法添加e->add(new GeometryComponent())。我假设这个特定的基础至少有一个virtual功能,在这种情况下,简单的解决方案是实现get为:

template <typename T>
T* get() {
   return dynamic_cast<T*>(m_component); // or whatever your member is
}

问题是您不想使用 RTTI,但您没有提供理由。常见的误解是 RTTI 很,如果是这种情况,请考虑分析以查看是否是您的情况。在大多数情况下, s 的缓慢dynamic_cast<>并不重要,因为dynamic_casts 在您的程序中很少发生。如果dynamic_cast<>是瓶颈,您应该重构以便您不使用它,这将是最好的解决方案。

一种更快的方法,(同样,如果您在这里遇到性能瓶颈,您应该重新设计,这将使其更快,但设计仍然会被破坏)如果您只想允许获得对象的完整类型,则可以使用typeid测试类型是否相等并static_cast执行向下转换的组合:

template <typename T>
T* get() {
   if (typeid(*m_component)==typeid(T))
      return static_cast<T*>(m_component);
   else
      return 0;
}

这是一个穷人的版本dynamic_cast。它会更快,但它只会让你转换为完整的类型(即指向的对象的实际类型,而不是它的任何中间基础)。

如果您愿意牺牲所有正确性(或者没有 RTTI:即没有虚函数),您可以static_cast直接执行此操作,但如果对象不是该类型,您将导致未定义的行为。

于 2012-11-04T18:50:21.493 回答