dynamic_cast如何工作? [英] How does dynamic_cast work?

查看:80
本文介绍了dynamic_cast如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您具有以下条件:

class Animal{};

class Bird : public Animal{};

class Dog : public Animal{};

class Penguin : public Bird{};

class Poodle : public Dog{};

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

Does dynamic_cast just check if one class is a derived class of another, or if one class is a base class of another? So if I had:

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 中?

bird would now point to an Animal class, so that I can use bird->some_function(); and it will call the function in Animal? And animal now points to a Bird class, so I can do animal->some_function(); and it will call some_function(); in Bird?

我一直在尝试弄清楚 dynamic_cast 的工作方式,而我在网上找到的资源并不是最有用.如果有人可以对 dynamic_cast 的功能以及某些有用的实例提供其他见解,我将不胜感激.

I've been trying to figure out how the dynamic_cast works, and the resources I've found online haven't been the most helpful. If someone can offer other insight into the functionality of dynamic_cast and some instances in which it would be useful, I'd highly appreciate it.

推荐答案

关于动态类型转换的最重要的一点是,它应该应用于多态类型.否则,动态转换的工作方式就类似于静态转换.

The most important thing about the dynamic cast is that it should be applied to a polymorphic type. Without that, dynamic cast works like a static cast.

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

What is a polymorphic type? Any class that has at least one virtual method or virtual destructor or virtual base class is polymorphic. Only those types have a virtual method table (VMT) in their data layout. Classes that do not have anything virtual do not have VMT's. The standard does not say how polymorphism and virtual methods should be implemented, yet all compilers, as far as I know, do this.

在您的示例中,类不是多态的.我认为,如果将动态类型转换应用于非多态类型,则编译器发出错误会更好.但是,他们不这样做.这加剧了混乱.

In your examples classes are not polymorphic. In my opinion, it would be better if compilers would issue an error when the dynamic cast is applied to a non-polymorphic type. Nevertheless, they do not do this. This adds to the confusion.

VMT指针是不同的.这意味着在运行时查看:

VMT pointers for all classes are different. This means that on the runtime looking at:

Animal* animal;

有可能知道对象的真实类是什么.是 Bird 还是 Dog 还是其他东西.从VMT的值知道真实类型,如果需要,生成的代码可以进行调整.

it is possible to know what the real class of the object is. Is it a Bird or a Dog or something else. Knowing the real type from the value of VMT, generated code can make an adjustment if this is needed.

这里是一个例子:

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);

请注意,生物不是第一基础类别.这意味着指针将移动以指向对象的右侧.尽管如此,以下内容仍将起作用:

Note that creature is not the first base class. This means that the pointer will be shifted to point to the right part of the object. Nevertheless, the following will still be working:

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

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

because VMT of Creature when it is part of other class will not be the same to VMT of the object when it is used stand-alone:

Creature *creature1 = new Creature();

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

This distinction allows a proper implementation of a dynamic cast. In the example Case2 the pointer will be shifted back. I tested this. This works.

这篇关于dynamic_cast如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆