如何通过 class 名称或类型比较两个对象(相当于 C++ 中 Java 的 `getClass()`)
How to compare two objects by class name or type (equivalent of Java's `getClass()` in C++)
我想通过 class 名称比较两个对象。第一个对象是 Card*
类型,它指向 MagicCard
对象,第二个对象是 MagicCard
类型 - Card
的子 class。当我将它们与 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.
}
上面的比较应该return对象是同一类型的,因为向量里面那个位置的元素我知道[=25=中有一个函数getClass()
] 所以我正在寻找 C++ 中的某种等效项,它通过派生 class 比较对象,而不是通过母体 class.
编辑:我根据 Peter 的建议更改了代码并添加了为什么我需要此检查的信息。还不行。
看typeid
几乎总是不正确的。
你可以用 dynamic_cast
从 Card *
得到一个 MagicCard *
,如果 Card *
不指向 [=],它将是一个空指针17=]对象。
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
class 是如何声明的。
根据 cppreference.com.
,typeid
不适用于非多态 classes
例如,如果您有以下程序,输出将如输出行旁边的注释所示:
#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;
}
如你所见,非多态派生classDerivedNonPoly
没有虚方法的对象无法识别其真实身份和returns其类型改为父 BaseNonPoly
。
正如 Caleth 的回答中提到的那样,根据具体派生的 class 类型避免特殊情况是一种很好的做法。但是,由于这不能总是以一种优雅的方式避免,因此对 Card
和 MagicCard
class 使用未使用的虚函数或虚析构函数可能就足够了 typeid
才能正常工作。
我想通过 class 名称比较两个对象。第一个对象是 Card*
类型,它指向 MagicCard
对象,第二个对象是 MagicCard
类型 - Card
的子 class。当我将它们与 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.
}
上面的比较应该return对象是同一类型的,因为向量里面那个位置的元素我知道[=25=中有一个函数getClass()
] 所以我正在寻找 C++ 中的某种等效项,它通过派生 class 比较对象,而不是通过母体 class.
编辑:我根据 Peter 的建议更改了代码并添加了为什么我需要此检查的信息。还不行。
看typeid
几乎总是不正确的。
你可以用 dynamic_cast
从 Card *
得到一个 MagicCard *
,如果 Card *
不指向 [=],它将是一个空指针17=]对象。
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
class 是如何声明的。
根据 cppreference.com.
typeid
不适用于非多态 classes
例如,如果您有以下程序,输出将如输出行旁边的注释所示:
#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;
}
如你所见,非多态派生classDerivedNonPoly
没有虚方法的对象无法识别其真实身份和returns其类型改为父 BaseNonPoly
。
正如 Caleth 的回答中提到的那样,根据具体派生的 class 类型避免特殊情况是一种很好的做法。但是,由于这不能总是以一种优雅的方式避免,因此对 Card
和 MagicCard
class 使用未使用的虚函数或虚析构函数可能就足够了 typeid
才能正常工作。