单个类的虚函数表
#include <iostream>
#include <Windows.h>
using namespace std;
class Father {
public:
virtual void func1() { cout << "调用虚函数Func1()" << endl; }
virtual void func2() { cout << "调用虚函数Func2()" << endl; }
virtual void func3() { cout << "调用虚函数Func3()" << endl; }
void func4() { cout << "调用普通函数Func4()" << endl; }
public:
int a = 10;
int b = 20;
};
//函数模板
typedef void(*type_t)(void);
int main(void) {
Father father;
cout << "father大小:" << sizeof(father) << endl; //12字节
cout << "father地址:" << &father << endl;
cout << (int*)*(int*)(&father) << endl;
//虚函数表指针, 取到对象的地址,再转成(int*),在访问里面的内容
int* vptr = (int*)*(int*)(&father);
cout << "调用第一个虚函数" << endl;
((type_t)(*(vptr + 0)))();
cout << "调用第二个虚函数" << endl;
((type_t)(*(vptr + 1)))();
cout << "调用第三个虚函数" << endl;
((type_t)(*(vptr + 2)))();
cout << "调用第一个数据成员" << endl;
cout << "地址:" << &father.a << endl;
cout << "值:"<< * (int*)((int)&father + 4) << endl;
cout << "调用第二个数据成员" << endl;
cout << "地址:" << &father.b << endl;
cout << "值:" << *(int*)((int)&father + 8) << endl;
system("pause");
return 0;
}
执行效果:
VS的对象内存分布分析:
项目的命令行配置中添加: /d1 reportSingleClassLayoutFather
手绘内存分布:
- 对象内,首先存储的是“虚函数表指针”,又称“虚表指针”。
然后再存储非静态数据成员。 - 对象的非虚函数,保存在类的代码中!
对象的内存,只存储虚函数表和数据成员
(类的静态数据成员,保存在数据区中,和对象是分开存储的) - 添加虚函数后,对象的内存空间不变!仅虚函数表中添加条目
多个对象,共享同一个虚函数表!