#单一虚拟继承
#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]);
}
打印结果
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|
#单一虚拟继承&多态(虚基类无虚函数)
#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();
}
}
打印结果
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()|
#案例二
虚基类有虚函数,但是子类没有重写该虚函数。
#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();
}
}
打印结果
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()|