博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++虚函数实现原理
阅读量:3529 次
发布时间:2019-05-20

本文共 900 字,大约阅读时间需要 3 分钟。

在C++中虚函数为派生出来的类提供统一的接口,虚函数的定义也很简单直接加上修饰关键之virtual(后面加上“=0”那就是纯虚函数了)就可以了,之后派生类中进行override。但是需要理解虚函数的调用基理还是的从内存地址的角度去理解它。

上面图中的左边是经常写的继承关系代码,右边是响应的对象在内存中的布局情况。这里讲到的virtual函数的实现机制要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数(基地址加上偏移量)。典型情况下,这一信息具有一种被称为 vptr(virtual table pointer,虚函数表指针)的指针的形式。vptr 指向一个被称为 vtbl(virtual table,虚函数表)的函数指针数组,每一个包含虚函数的类都关联到 vtbl。当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针。
因而,在上面的图中可以看到B、D的对象都包含了一个虚函数表。其中:(1)B的对象中的虚函数表中存放着B::foo()和B::bar()两个函数指针;(2)D的对象中的虚函数表中存放的既有继承自B的虚函数B::foo(),又有重写(override)了基类虚函数B::bar()的D::bar(),还有新增的虚函数D::quz()
那么既然每个类的对象中都维护了这样的一个虚函数表,那么在实际的调用过程中发生了什么?比如现在要调用下面的代码(下图左边):
在图片左边定义了一个函数test(),它传进去了一个B*的参数,那么这个参数就可能指向B的对象,也可能指向D的对象。那么当程序执行到“pb->bar()”时,已经能够判断pb指向的具体类型了:(定义一个函数指针占4字节,每个对象都有一个vptr)
(1)如果pb指向B的对象,可以获取到B对象的vptr,加上偏移值8((char*)vptr + 8),可以找到B::bar()
(2)如果pb指向D的对象,可以获取到D对象的vptr,加上偏移值8((char*)vptr + 8) ,可以找到D::bar()
                                                                      
你可能感兴趣的文章
【零】Linux中MySQL安装
查看>>
Sqoop的安装及测试
查看>>
Kylin的简单使用
查看>>
Presto的概念和安装使用
查看>>
Druid的Web页面使用
查看>>
Scala-HelloWorld
查看>>
Scala-IDEA中环境部署
查看>>
Scala-HelloWorld解析
查看>>
Scala-变量和数据类型
查看>>
Scala-流程控制
查看>>
Scala-面向对象后章
查看>>
iOS蓝牙原生封装,助力智能硬件开发
查看>>
iOS 代码的Taste(品位)
查看>>
iOS开发代码规范
查看>>
iOS组件化实践(基于CocoaPods)
查看>>
【iOS学习】RxSwift从零入手 - 介绍
查看>>
数据结构之栈
查看>>
Elastic Stack简介
查看>>
关于deepin系统安装design compiler的问题解答
查看>>
Java Agent简介及使用Byte Buddy和AspectJ LTW监控方法执行耗时
查看>>