如何按类名或类型比较两个对象(相当于 Java 在 C++ 中的"getClass()")



我想根据两个对象的类名来比较它们。第一个对象是指向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_castCard *获取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

尚不清楚CardMagicCard类是如何声明的。根据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的回答中提到的那样,根据具体派生的类类型避免特殊情况是一种很好的做法。然而,由于不能总是以优雅的方式避免这种情况,因此对CardMagicCard类使用一个未使用的虚拟函数或虚拟解构器可能就足够了,typeid才能正常工作。

最新更新