1 说明
众所周知,每个带有虚函数的类,或者继承具有虚函数类的对象,本身都是会有一个虚函数表的,前者为自身创建的,后者为继承,且虚函数表的指针位置位于类的首四位地址,如下图所示!
如何获取虚函数表地址?看下面代码:
Obj obj;
int vAddr = *(int *)(&obj); //获取虚函数表地址
首先获取类地址,将类地址强制转为int类型数据(int数据地址),该地址保存的数据又是虚函数表的地址,所以使用去除地址中的虚函数表地址。有点绕口,可以自行理解。
2 问题
同一个类,实例化两次,每个实例化的类到底是都有一个虚函数表?还是所有该类实例化的对象使用同一个虚函数表?即下面代码中
Obj obj_1;
Obj obj_2;
obj_1 和 obj_2 是使用同一个虚函数表吗?
先说答案! 所有实例是共用一个虚函数表。
3 测试
测试代码:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
MainWindow w2;
int vAddr_1 = *(int *)(&w);
int vAddr_2 = *(int *)(&w2);
printf("d_1:%i \n",vAddr_1);
printf("d_2:%i \n",vAddr_2);
w.show();
w2.show();
return a.exec();
}
结果显示d_1和d_2数值一致,也就是说,指向的是同一个地址!即w和w2使用的同一个虚函数表。
4 推测
为什么要共用同一个虚函数表?可能是为了节省内存吧,首先同一个类的对象虚函数都是一样的,没必要重新伴随构造生成一份一模一样的表,所以拷贝虚函数表的表地址就行。