C++复习小短篇】访问基类的私有函数
题目内容
该问题考察对虚函数表
的理解,虚函数表就是是一个类存储虚函数地址的指针列表,每一个声明的虚函数(不论是新建还是重写)都会写入虚函数表的对应位置。
虚函数表
的地址在vc
编译器下存储在每个对象内存空间的最前面,通过解引用可以访问虚函数表的首地址
,接下来我们可以通过遍历等方式访问里面存的函数地址。
代码如下
1 |
|
它的输出结果为:
1 | B::g |
关键代码解析
我们着重拆解这行代码
1 | pfun = (Fun_t)*((*(int***)(&b)) + i); |
- 获取虚表地址: 在vc编译器下虚表地址就是对象地址的第一段指针地址,所以使用
&b
获取虚表地址–(&b)
- 获取虚表首地址: 因为(&b)是
B*
类型的指针,所以我们要把它转换为列表类型的指针再解引用,所以添加(int***)
把它强转为int*
指针列表的地址指针,然后解引用获取虚函数列表首地址–(*(int***)(&b))
- 使用偏移量:我们要根据不同的偏移量获取不同的函数地址,所以需要偏移指针,同时为保证指针一定偏移了一个指针的长度,我们先前就把它转换成了
int*
指针列表的指针,因此加上常数时,移动的是一个指针长度的地址–((*(int***)(&b)) + i)
- 获取函数地址: 此时指针指向了列表的元素的地址,我们需要解引用才能访问元素,及函数地址,所以要先解引用–
*((*(int***)(&b)) + i)
- 存储函数指针:上面的方法我们已经获取了函数指针的值,但是它是
int*
类型的指针,所以还要强制转换一下–(Fun_t)*((*(int***)(&b)) + i)
- 执行函数:通过
pfun()
调用pfun
指针指向的函数
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 supdriver的博客!
评论