Dynamic_cast 是如何工作的?

2024-03-30

如果您有以下情况:

class Animal{};

class Bird : public Animal{};

class Dog : public Animal{};

class Penguin : public Bird{};

class Poodle : public Dog{};

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

Bird* bird;
Animal* animal;

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

bird现在将指向一个Animal类,以便我可以使用bird->some_function();它会调用该函数Animal? And animal现在指向一个Bird类,所以我可以做animal->some_function();它会调用some_function(); in Bird?

我一直在试图弄清楚如何dynamic_cast有效,而且我在网上找到的资源并不是最有帮助的。如果有人可以提供对功能的其他见解dynamic_cast以及在某些情况下它会很有用,我将非常感激。


关于动态转换最重要的事情是它应该应用于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指针将向后移动。我测试了这个。这有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dynamic_cast 是如何工作的? 的相关文章

  • Asp.net core默认路由

    简化版Startup code public void ConfigureServices IServiceCollection services services AddMvc public void Configure IApplica
  • Nullable 是不可能的,为什么不呢? [复制]

    这个问题在这里已经有答案了 如果这是一个愚蠢的问题 请原谅 我正在尝试更好地理解 Net 中的 Nullable 类型 从我从 Microsoft 源代码 使用 ReSharper 中注意到的内容 我了解到 Nullable 是一个结构 而
  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • 当其源是 https uri 时如何使 wpf MediaElement 播放

    在 wpf 独立应用程序 exe 中 我在主窗口中包含了 MediaElement
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • C# 和月历,选择多个日期

    我正在制作一个程序 可以帮助人们用 C 为某个部门 预订 订单 他们需要能够选择不同月份的多个日期 我更愿意拥有它 这样他们就可以单击一个日期 然后按住 Shift 键单击另一个日期以选择这两个日期之间的所有日期 并控制单击以进行单选 取消
  • 为什么在 C++ 中声明枚举时使用 typedef?

    我已经很多年没有写过任何 C 了 现在我正试图重新开始 然后我遇到了这个并考虑放弃 typedef enum TokenType blah1 0x00000000 blah2 0X01000000 blah3 0X02000000 Toke
  • C# Outlook 从收件人获取 CompanyName 属性

    我目前正在使用 C 编写 Outlook 2010 AddIn 我想要的是从我从 AppointmentItem 中提取的 Recipient 对象中获取 CompanyName 属性 因此 有了 AppointmentItem 的收件人
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 在 C 语言中替换宏内的宏

    我正在尝试使代码部分可重用 我下面的评论片段没有达到我想要的效果 define NAME ABC define LOG SIZE NAME LEN 我想LOG SIZE决心ABC LEN 我尝试过使用 但没能让它发挥作用 LOG SIZE在
  • 如果在代码中添加元素,“FindName”将不起作用

    在 WPF 应用程序中 如果在 XAML 中声明 ContentControl
  • C 与 C++ 中的 JNI 调用不同?

    所以我有以下使用 Java 本机接口的 C 代码 但是我想将其转换为 C 但不知道如何转换 include
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 不使用放置 new 返回的指针时的 C++ 严格别名

    这可能会导致未定义的行为吗 uint8 t storage 4 We assume storage is properly aligned here int32 t intPtr new void storage int32 t 4 I k
  • 初始化列表在 VC10 中不起作用

    我在 VC 2010 中编写了这个程序 class class1 public class1 initializer list

随机推荐