C++内存模型(二)

#单一虚拟继承

#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()|
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值