关于动态转换最重要的事情是它应该应用于polymorphic type
。没有它,动态转换就像静态转换一样工作。
什么是多态类型?任何具有至少一个虚拟方法或虚拟析构函数或虚拟基类的类都是多态的。只有那些类型有虚方法表(VMT)在他们的数据布局中。没有任何虚拟内容的类没有 VMT。标准没有说明多态性和虚方法应该如何实现,但据我所知,所有编译器都是这样做的。
在您的示例中,类不是多态的。在我看来,如果编译器在将动态转换应用于非多态类型时发出错误,那就更好了。然而,他们不这样做。这增加了混乱。
所有类的 VMT 指针都不同。这意味着在运行时查看:
Animal* animal;
可以知道对象的真实类别是什么。是不是一个Bird
or a 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
指针将向后移动。我测试了这个。这有效。