首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >C++中的dynamic_cast在没有RTTI的情况下不能工作;为什么?

C++中的dynamic_cast在没有RTTI的情况下不能工作;为什么?
EN

Stack Overflow用户
提问于 2018-02-16 00:11:56
回答 2查看 1.1K关注 0票数 4

虚方法在没有RTTI的情况下工作,这不是意味着在运行时有足够的数据来确定它是哪个类吗?

(我想知道如何向下转换,然后检查它是否是指向正确类型的指针。我不能修改涉及的类,也不能打开RTTI。)

EN

回答 2

Stack Overflow用户

发布于 2018-02-16 00:17:36

虚函数调度不需要类型信息,即动态类型的标识。

虚拟函数分派通常通过每个对象中的vtable指针实现,其中该指针指向指向函数实现的特定类型的指针表( "vtable")。

dynamic_casttypeid需要类型信息。

对于返回类型信息的typeid,该信息必须存在于可执行文件中的某个位置。当您关闭信息的存储时,它将不会被检索到。但是dynamic_cast呢?

在最简单的情况下,dynamic_cast是从一些基类型引用到派生类型引用的向下转换,即D&。派生类型不必是对象最派生的类型。因此,对于现在通用的用于动态分派的vtable方案,对象的vtable指针不需要指向D类型的vtable,因此不能提供简单的成功检查。

对于被限制为单一继承的语言,通过使用vtable本身作为类型标识符,通过在vtable中的父指针向上搜索(单一)继承链,可以解决纯粹的向下转换的情况。

有了多重继承,事情就变得复杂了。例如,如果类Derived继承自Base1Base2,其中两者都是多态的,那么Derived类的vtable不能简单地扩展Base1的vtable和简单地扩展Base2的vtable。因此,如果Derived vtable扩展了Base1,那么当一个代码重新解释为< Derived* >d16时,指向对象的Derived vtable指针将不再作为指向静态已知类的vtable的指针。

因此,一个后果是,在存在多重继承的情况下,转换为基类型引用并不总是简单地重新解释指针类型--指针值可能必须进行调整。

如何做到这一点并不明显,以至于Bjarne Stroustrup在向语言添加多重继承之前,必须向自己证明可以实现多重继承的vtable方案。

我不知道当前的编译器是如何处理它的,特别是对于dynamic_cast,但由于简单的vtable父指针不能用于多重继承,所以从逻辑上讲,编译器不能通过这种机制做到这一点:需要一些额外的支持数据结构,RTTI信息。

"我想知道如何向下转换,然后检查它是否是指向正确类型的指针。但是,我不能修改相关的类或打开RTTI。

如果您不能更改代码或打开RTTI,您通常无法获得所需的信息。

在控制所有对象实例化的特殊情况下,原则上可以维护一个单独的每个对象的类型信息映射,但这将是非常低效的。

票数 4
EN

Stack Overflow用户

发布于 2018-02-16 00:33:49

如果编译器在运行时插入了足够的数据来使dynamic_cast工作,那么它们也会插入足够的数据来使RTTI工作。如果您可以对另一个类型的引用执行dynamic_cast操作,则可以检查它是同一类型还是另一个类型的后代。因此,这等同于在默认情况下简单地打开RTTI。

例如,为什么编译器可能想要关闭它以提高效率,如果您的派生类没有覆盖其父类的任何虚函数,会发生什么情况?编译器可能希望它简单地重用相同的虚拟函数表。它也不需要跟踪基础关系和派生关系来进行函数分派。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48818312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文