问题描述
我想通过类名比较两个对象。第一个对象的类型为 Card*
,指向一个 MagicCard
对象,第二个对象的类型为 MagicCard
- Card
的子类。当我将它们与 typeid
进行比较时,它不起作用:
if (typeid(*(this->cards[index])) != typeid(card)) {
//the first object is of type Card* inside a vector and points to a
MagicCard object
//card is of type MagicCard
return false;
//this "if" check stops the method in case the types are different.
}
上面的比较应该返回对象是相同类型的,因为向量内那个位置的元素我知道Java中有一个函数getClass()
所以我正在寻找某种在 C++ 中等效,它通过派生类而不是母类比较对象。
编辑:我将代码更改为 Peter 的建议,并添加了为什么我需要此检查的信息。它还没有工作。
解决方法
看typeid
几乎总是不正确的。
你可以从带有MagicCard *
的{{1}}中得到一个Card *
,如果dynamic_cast
不指向{{1},它将是一个空指针} 对象。
Card *
然而,通常最好将 MagicCard
添加到 if (auto * magicCard = dynamic_cast<MagicCard>(cards[index])) {
// do something with magicCard
}
,并在 virtual void doSomething()
中覆盖它。
Card
,
不清楚您的 Card
和 MagicCard
类是如何声明的。
根据{{3}},typeid
不适用于非多态类。
例如,如果您有以下程序,则输出将如输出行旁边的注释所示:
#include <iostream>
#include <typeinfo>
class BaseNonPoly { };
class DerivedNonPoly : public BaseNonPoly { };
class BasePoly { virtual void foo() {} };
class DerivedPoly : public BasePoly { };
int main()
{
BaseNonPoly baseNonPoly;
DerivedNonPoly derivedNonPoly;
BasePoly basePoly;
DerivedPoly derivedPoly;
BaseNonPoly& pBaseNonPoly = baseNonPoly;
BaseNonPoly& pDerivedNonPoly = derivedNonPoly;
BasePoly& pBasePoly = basePoly;
BasePoly& pDerivedPoly = derivedPoly;
std::cout << "typeid(baseNonPoly)=" << typeid(baseNonPoly).name() << std::endl; // typeid(baseNonPoly)=11BaseNonPoly
std::cout << "typeid(derivedNonPoly)=" << typeid(derivedNonPoly).name() << std::endl; // typeid(derivedNonPoly)=14DerivedNonPoly
std::cout << "typeid(basePoly)=" << typeid(basePoly).name() << std::endl; // typeid(basePoly)=8BasePoly
std::cout << "typeid(derivedPoly)=" << typeid(derivedPoly).name() << std::endl; // typeid(derivedPoly)=11DerivedPoly
std::cout << "typeid(pBaseNonPoly)=" << typeid(pBaseNonPoly).name() << std::endl; // typeid(pBaseNonPoly)=11BaseNonPoly
std::cout << "typeid(pDerivedNonPoly)=" << typeid(pDerivedNonPoly).name() << std::endl; // typeid(pDerivedNonPoly)=11BaseNonPoly
std::cout << "typeid(pBasePoly)=" << typeid(pBasePoly).name() << std::endl; // typeid(pBasePoly)=8BasePoly
std::cout << "typeid(pDerivedPoly)=" << typeid(pDerivedPoly).name() << std::endl; // typeid(pDerivedPoly)=11DerivedPoly
return 0;
}
如您所见,没有虚方法的非多态派生类 DerivedNonPoly
的对象无法识别它的真实身份,而是返回其父类 BaseNonPoly
的类型。>
正如在 Caleth 的回答中提到的那样,根据具体的派生类类型避免特殊情况是一种很好的做法。然而,由于这不能总是以优雅的方式避免,因此对 Card
的 MagicCard
和 typeid
类使用未使用的虚函数或虚析构函数可能就足够了正常工作。