检查派生类的类型

时间:2012-05-07 13:51:11

标签: c++

在我的程序中,我有一个名为Entity的类。另一个类Invader继承实体。由于我想拥有4种不同类型的入侵者,因此我声明了继承自Invader的Invader1,Invader2,Invader3和Invader4类。现在我声明一个Entity指针类型向量来存储所有入侵者,如:

entities.push_back(new Invader4());
entities.push_back(new Invader3());
entities.push_back(new Invader2());
entities.push_back(new Invader1());
entities.push_back(new Invader0());

当我在运行时检查实体中元素的类型时,请说

typeid(*entities->at(index)) 

它可能会返回4种入侵者中的一种。在实体中还有其他继承实体的对象。所以我只想检查对象的类型是否是Invader,我不想知道它是Invader1,Invader2等。

我怎么能做到这一点?

4 个答案:

答案 0 :(得分:6)

在C ++中有很多方法可以做到这一点,但基本问题是,一旦你必须开始查询应该是多态的容器中的元素,你可能会放弃使用polimorphism的想法。拥有多态元素集合的全部意义在于,您可以对它们进行相同的处理。因此,如果您有vector<Entity*>,则只应将其元素视为Entity*。如果您发现需要在Invader上调用某些类似Entity的函数,那么最好还容纳Invader*的容器(使用与原始容器相同的指针) )。

答案 1 :(得分:3)

您可以检查dynamic_cast<Invader*>(entities->at(index))是否返回NULL(因为当指针未指向其类派生自{{1}的对象时,它会导致NULL指针})。

有关文档,请参阅this link

答案 2 :(得分:2)

创建一个继承自Invader的{​​{1}}类。让您的EntityInvader1等类继承自Invader2

然后,您可以添加Invader,在virtual bool IsInvader() const;中返回false,在Entity中添加true

答案 3 :(得分:1)

只是问这个问题通常意味着你实际上错过了界面中的虚拟功能。

如果你有类似的话:

if (myEntity->Type() == TypeInvader)
{
  static_cast<Invader*>(myEntity)->invade();
}

你几乎可以肯定通过添加

来重构它
virtual void tryInvade() {/* normally, entities don't invade*/}

在你的实体和

virtual void tryInvade() {invade(); /*but invaders do!*/}

在你的Invader课程中。

另一种选择是永远不会“失去”你的实体类型。如果您不想在这种情况下使用虚函数,那么您可能不应该通过引用它们的基类指针来存储这些实体,而应该作为指向您实际想要使用的类的指针。也就是说,您只需保留实体的类型,而不是稍后要求它。这可能表明您不应该使用继承,因为您违反了liskov substition principle相应的存储空间。