C++继承 - getClass()等价?

And*_*rew 8 c++ inheritance

以下面的C++为例.

vector<Animal> listAnimal;

class Fish : Animal ...
class Mammal : Animal ...
class Bird : Animal ...
Run Code Online (Sandbox Code Playgroud)

如果我然后将它们全部添加到列表中,然后从列表中任意抓取它们我不知道我正在处理哪个子类.我在Java中可以做getClass()thefish instanceof Fish.我如何在C++中执行此操作?

mig*_*tin 9

您不应该知道您正在处理的子类的类型.如果你需要检查你正在处理的类的类型,你就不会正确地执行多态.多态性的全部意义在于减少if并使代码更加灵活.

但是在某些情况下您需要知道并且可以使用RTTI,但我建议不要,特别是如果您需要很多性能(例如游戏或图形程序).

使用typeid运算符获取有关类的信息,并确定类是否为特定类型.

例如:

Animal* animal1 = new Cat;

if(typeid(animal1) == typeid(Cat))
{
     cout << "animal1 is a: " << typeid(Cat).name();
}
Run Code Online (Sandbox Code Playgroud)

然后使用a static_cast将其抛向hiearchy.

Animal* animal1 = new Cat;

if(typeid(animal1) == typeid(Cat))
{
     Cat* cat = static_cast<Cat*>(animal1);
     cat->scratchTheLivingHellOutOfYou();
}
Run Code Online (Sandbox Code Playgroud)

您可以使用dynamic_cast哪个更安全,但比typeid/static_cast慢得多.像这样:

Animal* animal1 = new Cat;

if(Cat* cat = dynamic_cast<Cat*>(animal1)
{
     cat->scratchTheLivingHellOutOfYou();
}
Run Code Online (Sandbox Code Playgroud)

编辑:

dynamic_cast因为它需要做一些额外的工作而不仅仅是测试它是否是特定类型和铸造,因此速度较慢.即dyanmic_cast不等同于typeid/static_cast,但它几乎是.

想象一个超过2级深度的层次结构,例如:

class Animal { /* ... */ }; // Base
class Cat : public Animal { /* ... */ }; // 2nd level
class Tiger : public Cat { /* ... */ }; // 3rd level
Run Code Online (Sandbox Code Playgroud)

让我们说在Cat类中,一个特定于所有Cats的方法被称为:scratchTheLivingHellOutOfYou().我们还要说:我有一个Animal*的列表,我想调用scratchTheLivingHellOutOfYou()列表中的每个Cat(这包括派生自Cat类的类).如果typeid操作员和static_cast使用,这将无法实现所需.由于typeid只检查当前类型而不关心层次结构.为此,您必须使用a dynamic_cast,因为它将检查类是否派生自基类,然后相应地向上/向下抛出层次结构.

你可以在这里用C++看到这个简单的例子.这是程序的输出:

USING TYPEID


*scratch*
meoyawnn!
RAWR



USING DYNAMIC_CAST


*scratch*
meoyawnn!
*scratch*
RAWR
Run Code Online (Sandbox Code Playgroud)

因此,你可以清楚地看到,dynamic_cast确实不是一个简单的多了很多的工作typeidstatic_cast.从dynamic_cast查找层次结构以查看它是否是特定类型.简单地说...... dynamic_cast可投了向下的层次结构.而a typeidstatic_cast只能将层次结构转换为特定类型.

我想提一下,如果dynamic_cast失败,它将返回一个NULL指针,或者如果你将它与引用一起使用则抛出异常.

笔记:

  1. 如果你真的需要性能并且你需要检查多态对象的类型,我建议找一个RTTI的替代品.比如使用模板/宏或其他任何来识别类.
  2. dynamic_cast只有在您不确定对象将是您要转换为的类型时才应使用.如果你作为程序员,知道你所投的任何东西是100%将成为那种类型然后使用static_cast,例如,如果你知道animal1 是一个Cat当时static_cast更合适.

  • 这是一个绝妙的答案。 (2认同)