cast函数_C++ GCC 对象模型 dynamic_cast实现 (Part 2)

dynamic_cast实现

dynamic_cast是C++语言的一部分,并不是STL

dynamic_cast is built in to the language. It does require an implementation, but there is no standardised location for the http:// implementation.In the gcc tool-chain, you can find some helper functions for the implementation in libsupc++.

对dynamic_cast进行反汇编,可以看到dynamic_cast会调用一个runtime library中的函数__dynamic_cast,

0x0000000000401800  

库函数__dynamic_cast需要四个参数:

extern 

__dynamic_cast的一个版本的代码见:这里 代码大概看了一下,可以分为这么几步,以下图的继承为例(不考虑虚继承)

7f6176d6b0a334a6968cf6250efe5697.png

假设B* pb = &c, v = pb, src = typeinfo of B, dst =X, E, A, D,不考虑src2dst_offset这个参数。

  • - 获得most_derived_object,即v所指对象本质上是什么对象,即c。这通过pb + top_offset即可做到。
  • - 在most_derived_object的继承树中查找dst类型(walk_object函数)这个函数是一个递归函数,本质上是递归当前结点(C)的所有子结点。复杂度为O(n),n为继承树中结点数量。
  • - 如果没找到dst,那就返回NULL
  • - 一般来说可以找到dst,那就通过offset(即虚函数表第一项)将指针从pb调整到所希望的位置
  • 比如: - dst = X, 则返回值指向c中的x部分 - dst = E,E不在以c为根的继承树中,返回NULL - dst = A, A是ambiguous的,返回NULL - dst = D,D在以c为根的继承树中,返回NULL

总结一下dynamic_cast:

dynamic_cast(src )实现继承树中的向上或向下转化,从target->src;

  • - 当发生向上转化时,比如dynamic_cast(C),这种转化是确保有效的,编译器通过加上offset即可完成,此时相当于static_cast(C*)
  • - 当发生向下转化时,要查看指针所指对象的实际类型,target在不在该对象的继承树内。
  • - 指针转化失败返回NULL,引用返回失败throw bad_cast 异常

参考资料:

[1] C++ RTTI的dynamic_cast函数 https://www.jianshu.com/p/778e5a4e4f29

[2] 多重继承中,每个虚表第一个槽中的type_info是对应base class还是全是derived class的类型? https://www.zhihu.com/search?type=content&q=typeinfo

[3] C++对象模型的规范 https://itanium-cxx-abi.github.io/cxx-abi/abi.html#rtti

typeinfo类

https://docs.microsoft.com/en-us/cpp/cpp/run-time-type-information?view=vs-2019​docs.microsoft.com

最后附上一张C++对象模型图:

4d94fb86700c5a6114f46a00cba434cf.png
  • [1] typeinfo也是一个多态类,所以第一个条目为虚函数表。
  • [2] _ZThn16_N7Class_C2fbEv 用于调整this指针
  • [3] 根据[Itanium ABI](

https://web.archive.org/web/20100315072857/http://www.codesourcery.com/public/cxx-abi/abi.html#mangling)规定的符合命名规范:

> <ctor-dtor-name> ::= C1 # complete object constructor
::= C2 # base object constructor
::= C3 # complete object allocating constructor
::= D0 # deleting destructor
::= D1 # complete object destructor
::= D2 # base object destructor

_ZN10__cxxabiv121__vmi_class_type_infoD0Ev 和_ZN10__cxxabiv121__vmi_class_type_infoD2Ev分别为该类的deleting destructor和base object destructor。具体的作用这里不作讨论。

相关代码如下:

#include 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值