C++ - 对象模型之 内存布局
C++对象模型目录
C++ - 对象模型之 编译器何时才会自行添加构造函数
C++ - 对象模型之 内存布局
C++ - 对象模型之 成员函数调用
C++ - 对象模型之 构造和析构函数都干了什么
C++ - 对象模型之 类对象在执行时是如何生成的
C++ - 对象模型之 模板、异常、RTTI的实现
C++ - 对象模型之 内存布局
class的static member不属于任何类对象,它保存在数据段,下面我们将对nonestatic member进行分析。
空类
#include <stdio.h>
class Child{
};
int main(){
Child child1;
Child child2;
printf("child1 : address(0x%p) size(%d)\n", &child1,sizeof(child1));
printf("child2 : address(0x%p) size(%d)\n", &child2,sizeof(child2));
printf("child1.char : 0x%02x\n",child1);
printf("child2.char : 0x%02x\n",child2);
}
X86 VC++
X86 g++
打印结果
child1 : address(0x0012FF63) size(1)
child2 : address(0x0012FF57) size(1)
child1.char : 0xcc
child2.char : 0xcc
打印结果
内存布局
Child Size: 1B
|char|
内存布局
Vtbl
Vtbl
其他
其他
无继承
#include <stdio.h>
class Child{
public:
int age;
};
int main(){
Child child1;
printf("child1 : address(0x%p) size(%d)\n", &child1,sizeof(child1));
printf("child1.age : address(0x%p)\n", &child1.age);
}
X86 VC++
X86 g++
打印结果
child1 : address(0x0012FF60) size(4)
child1.age : address(0x0012FF60)
打印结果
内存布局
Child Size:4B
|age|
内存布局
Vtbl
Vtbl
其他
其他
无继承&多态
#include <stdio.h>
typedef void(*Fun)(void);
class Child{
public:
int age;
Child():age(8){}
virtual void who(){ printf("I am child\n");}
virtual void study(){ printf("study...\n");}
};
int main(){
Child child;
Fun fun = NULL;
int * vtbl = (int *)(*((int*)&child));
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] is vptr, points to vtbl 0x%p\n",vtbl);
printf("child[1] is Age : %d\n", ((int *)(&child))[1]);
for (int i=0; (Fun)vtbl[i]!=NULL;i++){
fun = (Fun)vtbl[i];
printf("vtbl[%d] : ",i);
fun();
}
}
X86 VC++
X86 g++
打印结果
child(0x0012FF5C) : size(8)
child[0] is vptr, points to vtbl 0x0041587C
child[1] is Age : 8
vtbl[0] : I am child
vtbl[1] : study...
打印结果
内存布局
Child Size:8B
|vptr|age|
内存布局
Vtbl
|Child::who()|
|Child::study()|
Vtbl
其他
Vtbl存在堆上
其他
单一继承
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father:public GrandFather{
public:
Father():age(36){}
void cutting(){ printf("Father go to cutting...\n");}
int age;
};
class Child:public Father{
public:
Child():age(8){}
void studying(){ printf("Child go to studying...\n");}
int age;
};
int main(){
Child child;
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] is GrandFather : %d\n", ((int *)(&child))[0]);
printf("child[1] is Father : %d\n", ((int *)(&child))[1]);
printf("child[2] is child : %d\n", ((int *)(&child))[2]);
}
GrandFather
↑
Father
↑
ChildX86 VC++
X86 g++
打印结果
child(0x0012FF58) : size(12)
child[0] is GrandFather : 60
child[1] is Father : 36
child[2] is child : 8
打印结果
内存布局
Child Size:12B
|GrandFather::age|
|Father::age|
|Child::age|
内存布局
Vtbl
Vtbl
其他
其他
单一继承&多态
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void who(){ printf("I am GrandFather\n");}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
virtual void hungry(){ printf("GrandFather is hungry\n");}
int age;
};
class Father:public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Child : public Father{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
Fun fun = NULL;
int * vtbl = (int *)(*((int*)&child));
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] is vptr, points to vtbl 0x%p\n",vtbl);
printf("child[1] is GrandFather : %d\n", ((int *)(&child))[1]);
printf("child[2] is Father : %d\n", ((int *)(&child))[2]);
printf("child[3] is child : %d\n", ((int *)(&child))[3]);
for (int i=0; (Fun)vtbl[i]!=NULL;i++){
fun = (Fun)vtbl[i];
printf("vtbl[%d] : ",i);
fun();
}
}
GrandFather
↑
Father
↑
ChildX86 VC++
X86 g++
打印结果
child(0x0012FF54) : size(16)
child[0] is vptr, points to vtbl 0x004157FC
child[1] is GrandFather : 60
child[2] is Father : 36
child[3] is child : 8
vtbl[0] : I am Child
vtbl[1] : GrandFather go to fishing...
vtbl[2] : Child is hungry
vtbl[3] : Father go to cutting...
vtbl[4] : Child go to studying...
打印结果
内存布局
Child Size:16B
|vptr|
|GrandFather::age|
|Father::age|
|Child::age|
内存布局
Vtbl
|Child::who()|
|GrandFather::fishing()|
| Child::hungry()|
|Father::cutting()|
|Child::studying()|
Vtbl
其他
虚函数顺序是从base开始遍历
其他
多重继承
#include <stdio.h>
class GrandFather{
public:
GrandFather():age(60){}
int age;
};
class Grandad{
public:
Grandad():age(57){}
int age;
};
class Father:public GrandFather{
public:
Father():age(36){}
int age;
};
class Mother:public Grandad{
public:
Mother():age(34){}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] GrandFather : %d\n",pchild[0]);
printf("child[1] Father : %d\n",pchild[1]);
printf("child[2] Grandad : %d\n",pchild[2]);
printf("child[3] Mother : %d\n",pchild[3]);
printf("child[4] Child : %d\n",pchild[4]);
}
GrandFathe Grandad
^ ^
Father Mother
^
ChildX86 VC++
X86 g++
打印结果
child(0x0012FF50) : size(20)
child[0] : 60
child[1] : 36
child[2] : 57
child[3] : 34
child[4] : 8
打印结果
内存布局
Child Size:20B
|GrandFather::age|
|Father::age|
|Grandad::age|
|Mother::age|
|Child::age|
内存布局
Vtbl
Vtbl
其他
其他
多重继承&多态
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void who(){ printf("I am GrandFather\n");}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
virtual void hungry(){ printf("GrandFather is hungry\n");}
int age;
};
class Grandad{
public:
Grandad():age(57){}
virtual void who(){ printf("I am Grandad\n");}
virtual void chessing(){ printf("Grandad go to chessing...\n");}
virtual void hungry(){ printf("Grandad is hungry\n");}
int age;
};
class Father:public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Mother:public Grandad{
public:
Mother():age(34){}
virtual void who(){ printf("I am Mother\n");}
virtual void sewing(){ printf("Mother go to sewing...\n");}
virtual void hungry(){ printf("Mother is hungry\n");}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] vptr1 : 0x%p\n",pchild[0]);
printf("child[1] GrandFather : %d\n",pchild[1]);
printf("child[2] Father : %d\n",pchild[2]);
printf("child[3] vptr2 : 0x%p\n",pchild[3]);
printf("child[4] Grandad : %d\n",pchild[4]);
printf("child[5] Mother : %d\n",pchild[5]);
printf("child[6] Child : %d\n",pchild[6]);
Fun fun = NULL;
int * vtbl1 = (int *)pchild[0];
for (int i=0; (Fun)vtbl1[i]!=NULL; i++){
fun = (Fun)vtbl1[i];
printf("vtbl1[%d] : ", i);
fun();
}
int * vtbl2 = (int *)pchild[3];
for (int i=0; (Fun)vtbl2[i]!=NULL; i++){
fun = (Fun)vtbl2[i];
printf("vtbl2[%d] : ", i);
fun();
}
}
GrandFathe Grandad
^ ^
Father Mother
^
ChildX86 VC++
X86 g++
打印结果
child(0x0012FF48) : size(28)
child[0] vptr1 : 0x00416864
child[1] GrandFather : 60
child[2] Father : 36
child[3] vptr2 : 0x0041684C
child[4] Grandad : 57
child[5] Mother : 34
child[6] Child : 8
vtbl1[0] : I am Child
vtbl1[1] : GrandFather go to fishing...
vtbl1[2] : Child is hungry
vtbl1[3] : Father go to cutting...
vtbl1[4] : Child go to studying...
vtbl2[0] : I am Child
vtbl2[1] : Grandad go to chessing...
vtbl2[2] : Child is hungry
vtbl2[3] : Mother go to sewing...
打印结果
内存布局
Child Size:28B
|vptr1|
|GrandFather::age|
|Father::age|
|vptr2|
|Grandad::age|
|Mother::age|
|Child::age|
内存布局
Vtbl
Vtbl1:
|Child::who()|
|GrandFather::age|
|Child::hungry()|
|Father::cutting()|
|Child::studying()|
Vtbl2:
|Child::who()|
|Grandad::chessing()|
|Child::hungry()|
|Mother::sewing()|
Vtbl
其他
Child的独有虚函数,如studying,只在base1的vtbl进行记录。
其他
单一虚拟继承
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
int age;
};
class Child : public Father{
public:
Child():age(8){}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
int* pFather = (int*)pchild[0];//指向virtual base subobject的指针
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] pFather : 0x%p\n",pchild[0]);
printf("child[1] Father : %d\n",pchild[1]);
printf("child[2] Child : %d\n",pchild[2]);
/*通过pchild和pFather获得偏移量都可以获得virtual base 数据*/
printf("child[3] GrandFather : %d %d\n", pchild[3], *(int*)(((char *)pchild)+pFather[1]));
printf("pFather[0] : 0x%p\n",pFather[0], pFather[1]);
printf("pFather[1] Offset : %d\n", pFather[1]);
}
GrandFather
^
Father
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF54) : size(16)
child[0] pFather : 0x00415758
child[1] Father : 36
child[2] Child : 8
child[3] GrandFather : 60 60
pFather[0] : 0x00000000
pFather[1] Offset : 12
打印结果
内存布局
Child Size:16B
|vbase_pointer| pointer to vbase
|Father::age|
|Child::age|
|GrandFather::age|
内存布局
vbase
|vptr offset from vbase_pointer|
|vbase offset from vbase_pointer|
Vtbl
Vtbl
其他
寻址Virtual base object和Derivedvptr是通过offset来得到的
其他
单一虚拟继承&多态 一
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Child : public Father{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
Fun fun = NULL;
int* pchild = (int *)&child;
int* vbase_pointer = (int*)pchild[1];
int* vtbl = (int *)pchild[0];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] vtbl : 0x%p\n", vtbl);
printf("child[1] vbase_pointer : 0x%p\n", vbase_pointer);
printf("child[2] Father : %d\n", pchild[2]);
printf("child[3] Child : %d\n", pchild[3]);
printf("child[4] GrandFather : %d\n", pchild[4]);
printf("vbase_pointer[0] : %d\n", vbase_pointer[0]);
printf("vbase_pointer[1] vbase offset : %d\n", vbase_pointer[1]);
for (int i=0; (Fun)vtbl[i]!=NULL; i++){
fun = (Fun)vtbl[i];
printf("vtbl[%d] : ", i);
fun();
}
}
GrandFather
^
Father
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF50) : size(20)
child[0] vtbl : 0x00415778
child[1] vbase_pointer : 0x004164D8
child[2] Father : 36
child[3] Child : 8
child[4] GrandFather : 60
vbase_pointer[0] : -4
vbase_pointer[1] vbase offset : 12
vtbl[0] : I am Child
vtbl[1] : Father go to cutting...
vtbl[2] : Child is hungry
vtbl[3] : Child go to studying...
打印结果
内存布局
Child Size : 20B
|vptr|
|vbase_pointer|
|Father::age|
|Child::age|
|GrandFather::age|
内存布局
Vtbl
|Child::who()|
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
Vtbl
Vbase_table
|vptr offset from vbase_pointer|
|vbase offset from vbase_pointer|
其他
其他
单一虚拟继承&多态 二
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Child : public Father{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
Fun fun = NULL;
int* pchild = (int *)&child;
int* vbase_pointer = (int*)pchild[1];
int* vtbl = (int *)pchild[0];
int* vbase_vtbl = (int *)pchild[4];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] vtbl : 0x%p\n", vtbl);
printf("child[1] vbase_pointer : 0x%p\n", vbase_pointer);
printf("child[2] Father : %d\n", pchild[2]);
printf("child[3] Child : %d\n", pchild[3]);
printf("child[4] GrandFather vtbl : 0x%p\n", vbase_vtbl);
printf("child[5] GrandFather : %d\n", pchild[5]);
printf("vbase_pointer[0] : %d\n", vbase_pointer[0]);
printf("vbase_pointer[1] vbase offset : %d\n", vbase_pointer[1]);
for (int i=0; (Fun)vtbl[i]!=NULL; i++){
fun = (Fun)vtbl[i];
printf("vtbl[%d] : ", i);
fun();
}
for (int i=0; (Fun)vbase_vtbl[i]!=NULL; i++){
fun = (Fun)vbase_vtbl[i];
printf("vbase_vtbl[%d] : ", i);
fun();
}
}
GrandFather
^
Father
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF4C) : size(24)
child[0] vtbl : 0x0041577C
child[1] vbase_pointer : 0x0041640C
child[2] Father : 36
child[3] Child : 8
child[4] GrandFather vtbl : 0x0041594C
child[5] GrandFather : 60
vbase_pointer[0] : -4
vbase_pointer[1] vbase offset : 12
vtbl[0] : I am Child
vtbl[1] : Father go to cutting...
vtbl[2] : Child is hungry
vtbl[3] : Child go to studying...
vbase_vtbl[0] : GrandFather go to fishing...
打印结果
内存布局
Child Size : 24B
|vptr|
|vbase_pointer|
|Father::age|
|Child::age|
|GrandFather::vptr|
|GrandFather::age|
内存布局
Vtbl
Child vptr:
|Child::who()|
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
GrandFather vptr:
|GrandFather::fishing()|
Vtbl
Vbase_table
|vptr offset from vbase_pointer|
|vbase offset from vbase_pointer|
其他
其他
单一虚拟继承&多态 三
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void who(){ printf("I am GrandFather\n");}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Child : public Father{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
Fun fun = NULL;
int* pchild = (int *)&child;
int* vbase_pointer = (int*)pchild[1];
int* vtbl = (int *)pchild[0];
int* vbase_vtbl = (int *)pchild[5];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] vtbl : 0x%p\n", vtbl);
printf("child[1] vbase_pointer : 0x%p\n", vbase_pointer);
printf("child[2] Father : %d\n", pchild[2]);
printf("child[3] Child : %d\n", pchild[3]);
printf("child[4] : %.8x\n", pchild[4]);
printf("child[5] GrandFather vtbl : 0x%p\n", vbase_vtbl);
printf("child[6] GrandFather : %d\n", pchild[6]);
printf("vbase_pointer[0] : %d\n", vbase_pointer[0]);
printf("vbase_pointer[1] vbase offset : %d\n", vbase_pointer[1]);
for (int i=0; i<3; i++){
fun = (Fun)vtbl[i];
printf("vtbl[%d]: ",i);
fun();
}
for (int i=1; (Fun)vbase_vtbl[i]!=NULL; i++){
fun = (Fun)vbase_vtbl[i];
printf("vbase_vtbl[%d]: ", i);
fun();
}
}
GrandFather
^
Father
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF48) : size(28)
child[0] vtbl : 0x00416410
child[1] vbase_pointer : 0x004158BC
child[2] Father : 36
child[3] Child : 8
child[4] : 00000000
child[5] GrandFather vtbl : 0x0041577C
child[6] GrandFather : 60
vbase_pointer[0] : -4
vbase_pointer[1] vbase offset : 16
vtbl[0]: Father go to cutting...
vtbl[1]: Child is hungry
vtbl[2]: Child go to studying...
vbase_vtbl[1]: GrandFather go to fishing...
打印结果
内存布局
Child Size : 28B
|vptr|
|vbase_pointer|
|Father::age|
|Child::age|
|NULL|
|GrandFather::vptr|
|GrandFather::age|
内存布局
Vtbl
Child vptr:
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
GrandFather vptr:
|GrandFather::fishing()|
Vtbl
Vbase_table
|vptr offset from vbase_pointer|
|vbase offset from vbase_pointer|
其他
其他
多重虚拟继承
#include <stdio.h>
class GrandFather{
public:
GrandFather():age(60){}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
int age;
};
class Mother : virtual public GrandFather{
public:
Mother():age(34){}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
int* Father_vbase_pointer = (int *)pchild[0];
int* Mother_vbase_pointer = (int *)pchild[2];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] Father_vbase_pointer : %p\n",pchild[0]);
printf("child[1] Father : %d\n",pchild[1]);
printf("child[2] Mother_vbase_pointer : %p\n",pchild[2]);
printf("child[3] Mother : %d\n",pchild[3]);
printf("child[4] Child : %d\n",pchild[4]);
printf("child[5] GrandFather : %d\n",pchild[5]);
printf("Father_vbase_pointer[0] : %d\n",Father_vbase_pointer[0]);
printf("Father_vbase_pointer[1] vbase offset : %d\n",Father_vbase_pointer[1]);
printf("Mother_vbase_pointer[0] : %d\n",Mother_vbase_pointer[0]);
printf("Mother_vbase_pointer[1] vbase offset : %d\n",Mother_vbase_pointer[1]);
}
GrandFather
^ ^
Father Mother
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF4C) : size(24)
child[0] Father_vbase_pointer : 00415784
child[1] Father : 36
child[2] Mother_vbase_pointer : 0041577C
child[3] Mother : 34
child[4] Child : 8
child[5] GrandFather : 60
Father_vbase_pointer[0] : 0
Father_vbase_pointer[1] vbase offset : 20
Mother_vbase_pointer[0] : 0
Mother_vbase_pointer[1] vbase offset : 12
打印结果
内存布局
Child Size : 24B
|Father_vbase_pointer|
|Father::age|
|Mother_vbase_pointer|
|Mother::age|
|Child::age|
|GrandFather::age|
内存布局
Vtbl
Vtbl
Vbase_table
Father Vbase table
|Father vptr offset from Father_vbase_pointer |
|vbase offset from Father_vbase_pointer |
Mother Vbase table
|Mother vptr offset from Mother_vbase_pointer |
|vbase offset from Mother_vbase_pointer |
其他
其他
多重虚拟继承&多态 一
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Mother : virtual public GrandFather{
public:
Mother():age(34){}
virtual void who(){ printf("I am Mother\n");}
virtual void sewing(){ printf("Mother go to sewing...\n");}
virtual void hungry(){ printf("Mother is hungry\n");}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
int* Father_vtbl = (int *)pchild[0];
int* Father_vbase_pointer = (int *)pchild[1];
int* Mother_vtbl = (int *)pchild[3];
int* Mother_vbase_pointer = (int *)pchild[4];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] Father_vtbl : %p\n",Father_vtbl);
printf("child[1] Father_vbase_pointer : %p\n",Father_vbase_pointer);
printf("child[2] Father : %d\n",pchild[2]);
printf("child[3] Mother_vtbl : %d\n",Mother_vtbl);
printf("child[4] Mother_vbase_pointer : %d\n",Mother_vbase_pointer);
printf("child[5] Mother : %d\n",pchild[5]);
printf("child[6] Child : %d\n",pchild[6]);
printf("child[7] GrandFather : %d\n",pchild[7]);
printf("Father_vbase_pointer[0] : %d\n",Father_vbase_pointer[0]);
printf("Father_vbase_pointer[1] vbase offset : %d\n",Father_vbase_pointer[1]);
printf("Mother_vbase_pointer[0] : %d\n",Mother_vbase_pointer[0]);
printf("Mother_vbase_pointer[1] vbase offset : %d\n",Mother_vbase_pointer[1]);
Fun fun = NULL;
for (int i=0; i<4; i++){
fun = (Fun)Father_vtbl[i];
printf("Father_vtbl[%d] : ", i);
fun();
}
for (int i=0; (Fun)Mother_vtbl[i]!=NULL; i++){
fun = (Fun)Mother_vtbl[i];
printf("Mother_vtbl[%d] : ", i);
fun();
}
}
GrandFather
^ ^
Father Mother
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF44) : size(32)
child[0] Father_vtbl : 004168AC
child[1] Father_vbase_pointer : 00416980
child[2] Father : 36
child[3] Mother_vtbl : 4286780
child[4] Mother_vbase_pointer : 4286800
child[5] Mother : 34
child[6] Child : 8
child[7] GrandFather : 60
Father_vbase_pointer[0] : -4
Father_vbase_pointer[1] vbase offset : 24
Mother_vbase_pointer[0] : -4
Mother_vbase_pointer[1] vbase offset : 12
Father_vtbl[0] : I am Child
Father_vtbl[1] : Father go to cutting...
Father_vtbl[2] : Child is hungry
Father_vtbl[3] : Child go to studying...
Mother_vtbl[0] : I am Child
Mother_vtbl[1] : Mother go to sewing...
Mother_vtbl[2] : Child is hungry
打印结果
内存布局
Child Size : 32B
|Father vptr|
|Father_vbase_pointer|
|Father::age|
|Mother vptr|
|Mother_vbase_pointer|
|Mother::age|
|Child::age|
|GrandFather::age|
内存布局
Vtbl
Father vtbl
|Child::who()|
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
Mother vtbl
|Child::who()|
|Mother::sewing()|
|Child::hungry()|
Vtbl
Vbase_table
Father Vbase table
|Father vptr offset from Father_vbase_pointer |
|vbase offset from Father_vbase_pointer |
Mother Vbase table
|Mother vptr offset from Mother_vbase_pointer |
|vbase offset from Mother_vbase_pointer |
其他
Child::studying()只需要在第一个base中记录即可。
其他
多重虚拟继承&多态 二
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Mother : virtual public GrandFather{
public:
Mother():age(34){}
virtual void who(){ printf("I am Mother\n");}
virtual void sewing(){ printf("Mother go to sewing...\n");}
virtual void hungry(){ printf("Mother is hungry\n");}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
int* Father_vtbl = (int *)pchild[0];
int* Father_vbase_pointer = (int *)pchild[1];
int* Mother_vtbl = (int *)pchild[3];
int* Mother_vbase_pointer = (int *)pchild[4];
int* GrandFather_vtbl = (int *)pchild[7];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] Father_vtbl : %p\n",Father_vtbl);
printf("child[1] Father_vbase_pointer : %p\n",Father_vbase_pointer);
printf("child[2] Father : %d\n",pchild[2]);
printf("child[3] Mother_vtbl : %d\n",Mother_vtbl);
printf("child[4] Mother_vbase_pointer : %d\n",Mother_vbase_pointer);
printf("child[5] Mother : %d\n",pchild[5]);
printf("child[6] Child : %d\n",pchild[6]);
printf("child[7] GrandFather_vtbl : %d\n",GrandFather_vtbl);
printf("child[8] GrandFather : %d\n",pchild[8]);
printf("Father_vbase_pointer[0] : %d\n",Father_vbase_pointer[0]);
printf("Father_vbase_pointer[1] vbase offset : %d\n",Father_vbase_pointer[1]);
printf("Mother_vbase_pointer[0] : %d\n",Mother_vbase_pointer[0]);
printf("Mother_vbase_pointer[1] vbase offset : %d\n",Mother_vbase_pointer[1]);
Fun fun = NULL;
for (int i=0; i<4; i++){
fun = (Fun)Father_vtbl[i];
printf("Father_vtbl[%d] : ", i);
fun();
}
for (int i=0; i<3; i++){
fun = (Fun)Mother_vtbl[i];
printf("Mother_vtbl[%d] : ", i);
fun();
}
for (int i=0; i<3; i++){
fun = (Fun)GrandFather_vtbl[i];
printf("GrandFather_vtbl[%d] : ", i);
fun();
}
}
GrandFather
^ ^
Father Mother
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF40) : size(36)
child[0] Father_vtbl : 00416898
child[1] Father_vbase_pointer : 00416D34
child[2] Father : 36
child[3] Mother_vtbl : 4286768
child[4] Mother_vbase_pointer : 4286740
child[5] Mother : 34
child[6] Child : 8
child[7] GrandFather_vtbl : 4286788
child[8] GrandFather : 60
Father_vbase_pointer[0] : -4
Father_vbase_pointer[1] vbase offset : 24
Mother_vbase_pointer[0] : -4
Mother_vbase_pointer[1] vbase offset : 12
Father_vtbl[0] : I am Child
Father_vtbl[1] : Father go to cutting...
Father_vtbl[2] : Child is hungry
Father_vtbl[3] : Child go to studying...
Mother_vtbl[0] : I am Child
Mother_vtbl[1] : Mother go to sewing...
Mother_vtbl[2] : Child is hungry
GrandFather_vtbl[0] : GrandFather go to fishing...
打印结果
内存布局
Child Size : 36B
|Father vptr|
|Father_vbase_pointer|
|Father::age|
|Mother vptr|
|Mother_vbase_pointer|
|Mother::age|
|Child::age|
|GrandFather vptr|
|GrandFather::age|
内存布局
Vtbl
Father vtbl
|Child::who()|
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
Mother vtbl
|Child::who()|
|Mother::sewing()|
|Child::hungry()|
GrandFather vptr
| GrandFather::fishing()|
Vtbl
Vbase_table
Father Vbase table
|Father vptr offset from Father_vbase_pointer |
|vbase offset from Father_vbase_pointer |
Mother Vbase table
|Mother vptr offset from Mother_vbase_pointer |
|vbase offset from Mother_vbase_pointer |
其他
其他
多重虚拟继承&多态 三
#include <stdio.h>
typedef void(*Fun)(void);
class GrandFather{
public:
GrandFather():age(60){}
virtual void who(){ printf("I am GrandFather\n");}
virtual void fishing(){ printf("GrandFather go to fishing...\n");}
int age;
};
class Father : virtual public GrandFather{
public:
Father():age(36){}
virtual void who(){ printf("I am Father\n");}
virtual void cutting(){ printf("Father go to cutting...\n");}
virtual void hungry(){ printf("Father is hungry\n");}
int age;
};
class Mother : virtual public GrandFather{
public:
Mother():age(34){}
virtual void who(){ printf("I am Mother\n");}
virtual void sewing(){ printf("Mother go to sewing...\n");}
virtual void hungry(){ printf("Mother is hungry\n");}
int age;
};
class Child : public Father, public Mother{
public:
Child():age(8){}
virtual void who(){ printf("I am Child\n");}
virtual void studying(){ printf("Child go to studying...\n");}
virtual void hungry(){ printf("Child is hungry\n");}
int age;
};
int main(){
Child child;
int* pchild = (int *)&child;
int* Father_vtbl = (int *)pchild[0];
int* Father_vbase_pointer = (int *)pchild[1];
int* Mother_vtbl = (int *)pchild[3];
int* Mother_vbase_pointer = (int *)pchild[4];
int* GrandFather_vtbl = (int *)pchild[8];
printf("child(0x%p) : size(%d)\n",&child,sizeof(child));
printf("child[0] Father_vtbl : %p\n",Father_vtbl);
printf("child[1] Father_vbase_pointer : %p\n",Father_vbase_pointer);
printf("child[2] Father : %d\n",pchild[2]);
printf("child[3] Mother_vtbl : %d\n",Mother_vtbl);
printf("child[4] Mother_vbase_pointer : %d\n",Mother_vbase_pointer);
printf("child[5] Mother : %d\n",pchild[5]);
printf("child[6] Child : %d\n",pchild[6]);
printf("child[7] : %d\n",pchild[7]);
printf("child[8] GrandFather_vtbl : %d\n",GrandFather_vtbl);
printf("child[9] GrandFather : %d\n",pchild[9]);
printf("Father_vbase_pointer[0] : %d\n",Father_vbase_pointer[0]);
printf("Father_vbase_pointer[1] vbase offset : %d\n",Father_vbase_pointer[1]);
printf("Mother_vbase_pointer[0] : %d\n",Mother_vbase_pointer[0]);
printf("Mother_vbase_pointer[1] vbase offset : %d\n",Mother_vbase_pointer[1]);
Fun fun = NULL;
for (int i=0; i<3; i++){
fun = (Fun)Father_vtbl[i];
printf("Father_vtbl[%d] : ", i);
fun();
}
for (int i=0; i<2; i++){
fun = (Fun)Mother_vtbl[i];
printf("Mother_vtbl[%d] : ", i);
fun();
}
for (int i=1; i<3; i++){
fun = (Fun)GrandFather_vtbl[i];
printf("GrandFather_vtbl[%d] : ", i);
fun();
}
}
GrandFather
^ ^
Father Mother
^
Child
X86 VC++
X86 g++
打印结果
child(0x0012FF3C) : size(40)
child[0] Father_vtbl : 004168A4
child[1] Father_vbase_pointer : 00416F00
child[2] Father : 36
child[3] Mother_vtbl : 4286616
child[4] Mother_vbase_pointer : 4287796
child[5] Mother : 34
child[6] Child : 8
child[7] : 0
child[8] GrandFather_vtbl : 4286768
child[9] GrandFather : 60
Father_vbase_pointer[0] : -4
Father_vbase_pointer[1] vbase offset : 28
Mother_vbase_pointer[0] : -4
Mother_vbase_pointer[1] vbase offset : 16
Father_vtbl[0] : Father go to cutting...
Father_vtbl[1] : Child is hungry
Father_vtbl[2] : Child go to studying...
Mother_vtbl[0] : Mother go to sewing...
Mother_vtbl[1] : Child is hungry
GrandFather_vtbl[1] : GrandFather go to fishing...
打印结果
内存布局
Child Size : 40B
|Father vptr|
|Father_vbase_pointer|
|Father::age|
|Mother vptr|
|Mother_vbase_pointer|
|Mother::age|
|Child::age|
|NULL|
|GrandFather vptr|
|GrandFather::age|
内存布局
Vtbl
Father vtbl
|Father::cutting()|
|Child::hungry()|
|Child::studying()|
Mother vtbl
|Mother::sewing()|
|Child::hungry()|
GrandFather vptr
| GrandFather::fishing()|
Vtbl
其他
其他
#include <stdio.h>class Father{public:Father():age('f'){}virtual void who(){printf("I am Father\n");}char age;};class Child : public Father{public:Child():age('c'){}virtual void who(){printf("I am Child\n");}char age;};int main(){Child child;printf("child(0x%p) size(%d)\n",&child, sizeof(child));printf("child.Father::age(0x%p)\n",&child.Father::age);printf("child.age(0x%p)\n",&child.age);}
Child Size : 40B
|Father vptr|
|Father_vbase_pointer|
|Father::age|
|Mother vptr|
|Mother_vbase_pointer|
|Mother::age|
|Child::age|
|NULL|
|GrandFather vptr|
|GrandFather::age|Father Vbase table
|Father vptr offsetfrom Father_vbase_pointer | -4
|vbase offset from Father_vbase_pointer| 28
Mother Vbase table
|Mother vptr offsetfrom Mother_vbase_pointer | -4
|vbase offset from Mother_vbase_pointer | 16