C++ 检查派生类的类型
在我的程序中,我有一个名为Entity的类。另一个类入侵者继承实体。因为我想要有4种不同类型的入侵者,所以我声明了从入侵者继承的类INVIDER1、INVIDER2、INVIDER3和INVIDER4。现在我声明一个实体指针类型向量来存储所有入侵者,如:C++ 检查派生类的类型,c++,C++,在我的程序中,我有一个名为Entity的类。另一个类入侵者继承实体。因为我想要有4种不同类型的入侵者,所以我声明了从入侵者继承的类INVIDER1、INVIDER2、INVIDER3和INVIDER4。现在我声明一个实体指针类型向量来存储所有入侵者,如: entities.push_back(new Invader4()); entities.push_back(new Invader3()); entities.push_back(new Invader2()); entities.push_
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种入侵者中的一种。在实体中,还有其他继承实体的对象。所以我只想检查对象的类型是否是入侵者,我不想知道它是否是入侵者1,入侵者2,等等
如何实现这一点?您可以检查
dynamic_cast(entities->at(index))
是否返回notNULL
(因为当指针不指向类派生自入侵者的对象时,它将导致NULL
指针)
请参阅以获取一些文档。创建一个继承自实体的入侵者
类。让您的入侵者1
,入侵者2
,等等。类继承自入侵者
然后,您可以添加一个虚拟bool IsInvader()常量
在实体中返回false
,在入侵者中返回true
,仅问这个问题通常意味着您实际上在界面中缺少一个虚拟函数
如果您有以下情况:
if (myEntity->Type() == TypeInvader)
{
static_cast<Invader*>(myEntity)->invade();
}
在您的实体和
virtual void tryInvade() {invade(); /*but invaders do!*/}
在你的入侵者课上
另一个选择是永远不要“丢失”实体的类型。如果您不想在这种情况下使用虚拟函数,那么很有可能您不应该通过引用这些实体的基类指针来存储这些实体,而是将它们作为指向您实际想要使用的类的指针来存储。也就是说,您只需保留实体的类型,而不是稍后再请求它。这可能是一个标志,你不应该使用继承tho,因为你可能违反了相应的存储。 在C++中有很多方法可以做到这一点。但最基本的问题是,一旦您必须开始查询假定为多态的容器中的元素,您就可能放弃使用polimorphism的想法。拥有多态元素集合的全部意义在于,您可以对它们一视同仁。因此,如果你有一个向量
,你应该只把它的元素看作实体*
s。如果您发现需要在实体
上调用一些类似入侵者
的函数,那么您最好也持有一个入侵者*
的容器(使用与原始容器相同的指针)。在运行时需要知道类表明设计不好。您实际上想做什么?然后每次编写从实体
派生的类时,都向实体
添加一个iswhater()
?@juanchopanza虚拟常量char*getClassName()const代码>然后呢?@moooeeep这几乎是一样糟糕。必须查询“多态”集合中的每个元素的设计失去了多态性的所有好处,并且根本不可扩展。@juanchopanza每次编写从实体派生的类时,我的查询不是“IsWhather()to Entity?”。这显然是一个布尔查询,它捕获某些实体的公共属性,尽管不是所有实体。您正在查询某个语义属性,该属性恰好与类型有逻辑联系,而不是类型本身。我完全同意。这就是liskov原理的全部要点!是的,你是对的。在尝试使用多态性时使用类型检查有点尴尬。但对于一些罕见的情况,我似乎必须检查类型并使对象的功能不同。我会努力改进我的课程结构。谢谢你的帮助!
virtual void tryInvade() {invade(); /*but invaders do!*/}