c++ - dynamic_cast 是如何工作的?

标签 c++ dynamic dynamic-cast

如果您有以下情况:

class Animal{};

class Bird : public Animal{};

class Dog : public Animal{};

class Penguin : public Bird{};

class Poodle : public Dog{};

dynamic_cast 是否只检查一个类是否是另一个类的派生类,或者一个类是否是另一个类的基类?所以如果我有:

Bird* bird;
Animal* animal;

bird = dynamic_cast<Animal*>(bird);
animal = dynamic_cast<Bird*>(animal);

bird 现在将指向一个 Animal 类,这样我就可以使用 bird->some_function(); 它会调用Animal 中的函数? animal 现在指向一个 Bird 类,所以我可以执行 animal->some_function(); 它会调用 some_function( );Bird?

我一直试图弄清楚 dynamic_cast 的工作原理,但我在网上找到的资源并不是最有帮助的。如果有人能对 dynamic_cast 的功能和一些有用的实例提供其他见解,我将不胜感激。

最佳答案

动态转换最重要的一点是它应该应用于多态类型。没有它,动态转换就像静态转换一样工作。

什么是多态类型?任何具有至少一个虚拟方法或虚拟析构函数或虚拟基类的类都是多态的。只有这些类型在其数据布局中具有虚拟方法表 (VMT)。没有任何虚拟的类没有 VMT。该标准没有说明应该如何实现多态性和虚方法,但据我所知,所有编译器都这样做。

在您的示例中,类不是多态的。在我看来,如果将动态转换应用于非多态类型时编译器会发出错误会更好。然而,他们不这样做。这增加了困惑。

所有类的 VMT 指针都不同。这意味着在运行时查看:

Animal* animal;

可以知道对象的真正类别是什么。它是 Bird 还是 Dog 或其他东西。从 VMT 的值知道真正的类型,生成的代码可以根据需要进行调整。

这是一个例子:

class Animal   { virtual ~Animal();   int m1; };
class Creature { virtual ~Creature(); int m2; };

class Bird : public Animal, Creature { };

Bird *bird = new Bird();
Creature *creature = dynamic_cast<Creature*>(bird);

请注意,生物不是第一个基类。这意味着指针将移动到指向对象的右侧部分。尽管如此,以下内容仍然有效:

Animal *animal = dynamic_cast<Animal*>(creature);   // Case2.

因为 Creature 属于其他类的 VMT 与单独使用时对象的 VMT 不同:

Creature *creature1 = new Creature();

这种区别允许正确实现动态转换。在示例 Case2 中,指针将向后移动。我对此进行了测试。这行得通。

关于c++ - dynamic_cast 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13783312/

相关文章:

c++ - 如何 dynamic_cast 参数中带有不匹配引用修饰符的可变参数模板?

c++ - 不能使用 dynamic_cast 从 Base 转换为 Derived

c++ - 使用 QToolBox,哪个设置可以让页面只有它的内容大小?

java - 应该使用多个循环或一个循环并检查内部条件

C++ float 比较

c - 释放 struct.name 的内存(调试错误 : HEAP CORRUPTION DETECTED)

c# - PetaPoco 存储过程错误 "Incorrect syntax near the keyword ' FROM'。"}

c++ - 如何以多态方式无限嵌套对象

java - 如何创建动态二维数组并在其中存储打乱数组

c++ - vptr 是否曾经位于对象的开头?