在c++中虚函数的继承会生成一个虚函数表,来确定父类指针指向子类对象时所需要调用的具体的方法,用以实现多态。那么可不可以像静态方法一样直接调用类中的虚函数呢,答案是可行的
虚函数表在内存中的分布
这个东西可以去百度
大致原理如下:
通过虚函数表的地址直接调用虚函数
如题,在子类对象中,首地址存在一个指向虚函数表的地址,虚函数表中保存着子类具体需要调用的函数地址,代码如下
1 | class A { |
我们先定义一个父类和两个子类,父类中有一个虚函数,子类分别重写这个虚函数
1 | int main() { |
定义一个数组,数组中有一个父类对象和两个子类对象,循环调用数组元素的fun()函数,结果如下
现在我们了解了虚函数表在内存中的位置,那么可以通过特定的方法直接调用虚函数
1 | int objAddress = (int)&pObj[0]; //objAddress的地址是对象的地址 |
没有通过类对象,也可以调用到类内的函数
同样,还有一种更为高级的写法(来自韦老师的代码)
1 | uint32_t objAddress = (uint32_t)pObj[0]; |
上述代码也可以不通过类对象调用类内函数
修改虚函数表改变函数调用
我们知道,如果可以直接调用函数,那么应该有方法来替换掉虚函数表中函数的地址,把他改成我们想要执行的函数
现在,我们先来创建一个想要被执行的函数
1 | void g_fun() { |
把原来要执行的虚函数替换成我们想要让他执行的函数(来自韦老师的代码)
1 | //获取虚函数表的地址 |
通过上述代码可以达到修改虚函数表的目的