我一直在网上搜索,如果两个多态对象是同一类型,或者多态对象是一个类型,我似乎找不到任何替代方法进行比较。这是因为我要在我正在创建的游戏中实现一个实体系统。
除了使用宏或强制转换(演员不是这样做的可移植方法)之外,我还没有找到另一种方法。目前这就是我识别对象的方式,有没有更有效或更有效的方法呢? (不使用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
答案 0 :(得分:3)
请参阅std::is_polymorphic
。我相信也有提升。
如果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);
在剥离类型信息之前创建结构。
答案 1 :(得分:0)
如果你决定不使用C ++的内置RTTI,你可以通过从包含虚方法的基类派生所有类来自己重新实现它:
class Base {
public:
virtual string getType() = 0;
};
然后,每个派生类都需要使用返回不同字符串的版本重载此方法:
class Foo : public Base {
public:
string getType() { return "Foo"; }
};
然后,您可以简单地比较每个对象上调用getType()
的结果,以确定它们是否属于同一类型。如果您事先知道将要创建的所有派生类,则可以使用枚举而不是string
。
答案 2 :(得分: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 慢,如果是这种情况,请考虑分析以查看是否属于您的情况。在大多数情况下,dynamic_cast<>
的缓慢并不重要,因为dynamic_cast
在您的程序中很少发生。如果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
,但如果该对象不属于该类型,则会导致未定义的行为。< / p>