如何实现dynamic_cast [英] How is dynamic_cast implemented

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

问题描述

考虑这个简单的层次结构:

  class Base {public:virtual〜Base(){}}; 
class Derived:public Base {};

尝试向下转换 Base * p code>可以使用 dynamic_cast< Derived *>(p)来派生我以前认为 dynamic_cast 通过比较 p 中的vtable指针和但是如果我们从 Derived 派生另一个类,该怎么办呢?

我们现在有:

  class Derived2:public Derived {}; 

在这种情况下:

  Base * base = new Derived2; 
Derived * derived = dynamic_cast< Derived *>(base);

我们仍然得到一个成功的downcast,即使vtable指针在 Derived2 Derived 中的vtable指针无关。



它实际如何工作?如何 dynamic_cast 知道 Derived2 是否源自派生 (如果 Derived 在不同的库中声明)



am 有关具体细节如何实际工作(最好在GCC,但其他人也很好)。此问题此问题的重复。 (不指定其实际工作原理)。

解决方案


如何 dynamic_cast 知道 Derived2 是否源自派生 $ c> Derived 是在不同的库中声明的)


dynamic_cast 可以通过保持这些知识来了解这一点。



当编译器生成代码时,类层次结构在 dynamic_cast 可以查找的某种表中。该表可以附加到vtable指针,以便通过 dynamic_cast 实现来查找。 typeid 用于这些类的数据也可以与这些类一起存储。



如果涉及库,通常需要在库中公开这些类型的信息结构,就像函数一样。例如,有可能得到一个链接器错误,看起来像未定义的引用到'vtable for XXX'(和男孩,是那些恼人!),再次,就像函数一样。


Consider this simple hierarchy:

class Base { public: virtual ~Base() { } };
class Derived : public Base { };

Trying to downcast Base* p to Derived* is possible using dynamic_cast<Derived*>(p). I used to think dynamic_cast works by comparing the vtable pointer in p to the one in a Derived object.

But what if we derive another class from Derived? We now have:

class Derived2 : public Derived { };

In this case:

Base* base = new Derived2;
Derived* derived = dynamic_cast<Derived*>(base);

We still get a successful downcast, even though the vtable pointer in Derived2 has nothing to do with a vtable pointer in Derived.

How does it actually work? How can the dynamic_cast know whether Derived2 was derived from Derived (what if Derived was declared in a different library)?

I am looking for specific details about how this actually works (preferably in GCC, but others are fine too). This question is not a duplicate of this question (which doesn't specify how it actually works).

解决方案

How can the dynamic_cast know whether Derived2 was derived from Derived (what if Derived was declared in a different library)?

The answer to that is surprisingly simple: dynamic_cast can know this by keeping this knowledge around.

When the compiler generates code it keeps around the data about the class hierarchies in some sort of table that dynamic_cast can look up later. That table can be attached to the vtable pointer for easy lookup by the dynamic_cast implementation. The data neeeded for typeid for those classes can also be stored along with those.

If libraries are involved, this sort of thing usually requires these type information structures to be exposed in the libraries, just like with functions. It is possible, for example, to get a linker error that looks like "Undefined reference to 'vtable for XXX'" (and boy, are those annoying!), again, just like with functions.

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

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