我想根据两个对象的类名来比较它们。第一个对象是指向MagicCard
对象的Card*
类型,第二个对象是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
几乎总是不正确的。
您可以使用dynamic_cast
从Card *
获取MagicCard *
,如果Card *
没有指向MagicCard
对象,则它将是一个空指针。
if (auto * magicCard = dynamic_cast<MagicCard>(cards[index])) {
// do something with magicCard
}
然而,通常最好将virtual void doSomething()
添加到Card
,并在MagicCard
中覆盖它。
cards[index]->doSomething(); // no mention of MagicCard needed
尚不清楚Card
和MagicCard
类是如何声明的。根据cppreference.com.,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
才能正常工作。