【问题标题】:How dynamic casts work?动态演员表是如何工作的?
【发布时间】:2010-12-14 04:00:08
【问题描述】:

假设我有类型 A 和派生类型 B。当我执行从 A* 到 B* 的动态转换时,环境执行什么样的“运行时检查”?它怎么知道演员表是合法的?
我假设在 .Net 中可以在对象的标头中使用附加的元数据,但是在 C++ 中会发生什么?

【问题讨论】:

    标签: c++ casting polymorphism oop


    【解决方案1】:

    动态转换执行运行时检查这是否是有效且可行的转换;当无法执行强制转换时,它将返回 NULL。

    【讨论】:

    • 或者如果在引用类型上它会抛出 std::bad_cast
    【解决方案2】:

    动态投射是一个两步过程:

    1. 给定指向对象的指针的 vtable,使用偏移量恢复指向完整类的指针。 (然后将从此指针进行所有调整。)这相当于向下转换为整个类。

    2. 在整个类的 type_info 中搜索我们想要的类型 - 换句话说,浏览所有基的列表。如果我们找到一个,使用偏移量再次调整指针。如果第 2 步搜索失败,则返回 NULL。

    【讨论】:

      【解决方案3】:

      参考您最喜欢的 RTTI 书籍。

      【讨论】:

        【解决方案4】:

        确切的算法是编译器特定的。以下是它根据Itanium C++ ABI (2.9.7) 标准(写在 GCC 之后编写)的工作原理。

        指向基类的指针是指向“大”类主体中间的指针。 “大”类的主体以这样一种方式组装,即无论您的指针指向什么基类,您都可以统一访问该“大”类的 RTTI,而您的“基”类实际上是时间>。这个 RTTI 是一个特殊的结构,它与“大”类信息相关:它是什么类型,它有什么基础以及它们的偏移量。

        其实就是类的“元数据”,只是更“二进制”的风格。

        V instance;
        Base *v = &instance;
        dynamic_cast<T>(v);
        

        动态转换利用了这样一个事实,即当您编写 dynamic_cast&lt;T&gt;(v) 时,编译器可以立即识别 v 的“大”类的元数据——即 V!当编写它时,你认为TBase更派生,因此编译器将很难进行base-to-drived cast。但是编译器可以立即(在运行时)确定最衍生的类型--V--然后它只需要遍历元数据中包含的继承图来检查它是否可以将V 向下转换为T。如果可以,它只检查偏移量。如果它不能或不明确 - 返回NULL

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-23
          • 2017-12-22
          • 1970-01-01
          • 2014-10-24
          • 1970-01-01
          • 1970-01-01
          • 2014-10-20
          相关资源
          最近更新 更多