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

标签 c++ inheritance

以下面的C++为例。

vector<Animal> listAnimal;

class Fish : Animal ...
class Mammal : Animal ...
class Bird : Animal ...

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

最佳答案

您不需要知道您正在处理的是什么类型的子类。如果您需要检查正在处理的类的类型,那么您就没有正确地进行多态性处理。多态性的全部意义在于减少 if 并使您的代码更加灵活。

有些情况需要知道,可以用RTTI为了那个原因。但是我建议不要这样做,尤其是当您需要大量性能时(例如游戏或图形程序)。

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

例如:

Animal* animal1 = new Cat;

if(typeid(animal1) == typeid(Cat))
{
     cout << "animal1 is a: " << typeid(Cat).name();
}

然后使用 static_cast 将其向下转换。

Animal* animal1 = new Cat;

if(typeid(animal1) == typeid(Cat))
{
     Cat* cat = static_cast<Cat*>(animal1);
     cat->scratchTheLivingHellOutOfYou();
}

或者,您可以使用 dynamic_cast,它更安全,但比 typeid/static_cast 慢得多。像这样:

Animal* animal1 = new Cat;

if(Cat* cat = dynamic_cast<Cat*>(animal1)
{
     cat->scratchTheLivingHellOutOfYou();
}

编辑:

dynamic_cast 比较慢,因为它必须做一些额外的工作,而不仅仅是测试它是否是特定类型和转换。即 dyanmic_cast 不等同于 typeid/static_cast,但几乎是。

想象一个比 2 层更深的层次结构,例如:

class Animal { /* ... */ }; // Base
class Cat : public Animal { /* ... */ }; // 2nd level
class Tiger : public Cat { /* ... */ }; // 3rd level

假设在 Cat 类中,调用了一个特定于所有 Cats 的方法:scratchTheLivingHellOutOfYou()。我们还可以这么说:我有一个 Animals 列表,我想为列表中的每只 Cat 调用 scratchTheLivingHellOutOfYou()(这包括派生自 Cat 类的类)。如果使用 typeid 运算符和 static_cast,这将无法达到要求,因为 typeid 只检查当前类型而不关心关于层次结构。为此,您必须使用 dynamic_cast,因为它将检查类是否派生自基类,然后相应地向上/向下转换层次结构。

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

USING TYPEID


*scratch*
meoyawnn!
RAWR



USING DYNAMIC_CAST


*scratch*
meoyawnn!
*scratch*
RAWR

因此,您可以清楚地看到 dynamic_cast 比简单的 typeidstatic_cast 做了更多的工作。由于 dynamic_cast 查找层次结构以查看是否 它是特定类型。简单地说... dynamic_cast 可以在层次结构中向上 转换。而 typeidstatic_cast 只能将层次结构向下转换为特定类型。

我想我会提到,如果 dynamic_cast 失败,它将返回 NULL 指针,或者如果您将它与引用一起使用,则会抛出异常。

注意事项:

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

关于C++ 继承 - getClass() 等效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531978/

相关文章:

c++ - Qt 模型 View 编程。 QAbstractItemModel 和 QAbstractListModel。索引()和父级()

德尔福7 : an abstract class through VFI

java - 在 Java 中删除对象时出现问题

java - scala 中的模式匹配。当参数表现出多态性或者是子类时,会有什么行为::

c# - 从父类(super class)获取字段

c++ - C中的&&&&操作是什么

c++ - 除以零时抛出什么类型的异常?

C++ srand,DLL 中的 rand 奇怪行为

c++ - 使用 boost iostreams 读取和写入数组到压缩文件

java - 重写父类(super class)继承的方法