源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C/C++杂记 虚函数的实现的基本原理(图文)

  • 时间:2020-06-26 06:48 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C/C++杂记 虚函数的实现的基本原理(图文)
[b]1. 概述[/b] 简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针。例: [img]http://files.jb51.net/file_images/article/201606/201606111248456.png[/img] 其中: B的虚函数表中存放着B::foo和B::bar两个函数指针。 D的虚函数表中存放的既有继承自B的虚函数B::foo,又有重写(override)了基类虚函数B::bar的D::bar,还有新增的虚函数D::quz。 [i]提示:为了描述方便,本文在探讨对象内存布局时,将忽略内存对齐对布局的影响。[/i] [b]2. 虚函数表构造过程[/b] 从[url=http://www.07net01.com/tags-%E7%BC%96%E8%AF%91%E5%99%A8-0.html]编译器[/url]的角度来说,B的虚函数表很好构造,D的虚函数表构造过程相对复杂。下面给出了构造D的虚函数表的一种方式(仅供参考): [img]http://files.jb51.net/file_images/article/201606/201606111248457.png[/img] [i]提示:该过程是由编译器完成的,因此也可以说:虚函数替换过程发生在编译时。[/i] [b]3. 虚函数调用过程[/b] 以下面的[url=http://www.07net01.com/tags-%E7%A8%8B%E5%BA%8F-0.html]程序[/url]为例: [img]http://files.jb51.net/file_images/article/201606/201606111248468.png[/img] 编译器只知道pb是B*类型的指针,并不知道它指向的具体对象类型 :pb可能指向的是B的对象,也可能指向的是D的对象。 但对于“pb->bar()”,编译时能够确定的是:此处operator->的另一个参数是B::bar(因为pb是B*类型的,编译器认为bar是B::bar),而B::bar和D::bar在各自虚函数表中的偏移位置是相等的。 无论pb指向哪种类型的对象,只要能够确定被调函数在虚函数中的偏移值,待运行时,能够确定具体类型,并能找到相应vptr了,就能找出真正应该调用的函数。 [i]提示:本人曾在“C/C++杂记:深入理解数据成员指针、函数成员指针”一文中提到:虚函数指针中的ptr部分为虚函数表中的偏移值(以字节为单位)加1。[/i] B::bar是一个虚函数指针, 它的ptr部分内容为9,它在B的虚函数表中的偏移值为8(8+1=9)。 当程序执行到“pb->bar()”时,已经能够判断pb指向的具体类型了:
[url=http://shouce.jb51.net/cxx-abi/abi.html]Itanium C++ ABI[/url]。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部