参考链接:C++ 虚基类表指针字节对齐模型
题目:
分别给出下面的类型Fruit和Apple的类型大小(即对象size),并通过画出二者对象模型图以及你的测试来解释该size的构成原因。
声明:编译器是VC6.0
对象模型图
黑色部分是我没有找到什么官方文档来解释,但是找到一边博客,并且被CSDN的C++知识库收录,应该尤其权威性。
隐藏成员的加入不能影响在其后的成员的对齐
#include <iostream>
class Fruit
{
public:
void print()
{
printf("void print()\n");
}
virtual void process()
{
printf("void process()\n");
}
private:
int no;
double weight;
char key;
};
class Apple: public Fruit{
public:
void save() { }
virtual void process(){ printf("Apple\n"); }
private:
int size;
char type;
};
typedef void(*voidfunc)(void);
int main(int argc, char *argv[])
{
Fruit f;
void *p = (void*)&f;
voidfunc func;
func= (voidfunc)*((int*)*(int*)(&f)); //下面有讲解
func();
printf("f.vptr = %p\n", &f);
printf("f.vptr_func1 = %p\n", *(int*)&f);
printf("func_process = %p\n", &Fruit::process);
printf("sizeof(Fruit) = %d\n", sizeof(Fruit));
printf("-----------------------------------------------------\n");
Apple a;
func= (voidfunc)*((int*)*(int*)(&a));
func();
printf("sizeof(Apple) = %d\n", sizeof(Apple));
return 0;
}
虚函数表指针位于指针的开始
func= (voidfunc)*((int*)*(int*)(&f));
&f ----> Fruit的地址
(int*)(&f)) ----> 强制转成int* 地址
*(int*)(&f)) 获取虚函数表的地址
(int*)*(int*)(&f) 强转虚函数表的第一个元素的地址
*((int*)*(int*)(&f)) 获取虚函数表中第一个元素的内容,也就是第一个虚函数的地址