c++ 继承 33 虚继承对c++ 对象内存模型造成的影响

来源:互联网 发布:linux 部署gitlab 编辑:程序博客网 时间:2024/05/14 05:16


#include <iostream>using namespace std;class BB{public:int bb_;};class B1:virtual public BB{public:int b_;};class B2:virtual public BB{public:int b2_;};class DD:public B1,public B2{public:int dd_;};int main(void){cout<<sizeof(BB)<<endl;//4cout<<sizeof(B1)<<endl;//12cout<<sizeof(DD)<<endl;//24  return 0;}
 根据以前的理论:BB,4个字节,B1,8个字节,DD 16个字节。。

推导B1的内存模型:

地址打印输出:

B1 b1;
cout<<&b1<<endl;
cout<<&b1.bb_<<endl;
cout<<&b1.b_<<endl;

 打印结果:

     0024F8D4
     0024F8DC
     0024F8D8

#include <iostream>using namespace std;class BB{public:int bb_;};class B1:virtual public BB{public:int b_;};class B2:virtual public BB{public:int b2_;};class DD:public B1,public B2{public:int dd_;};int main(void){cout<<sizeof(BB)<<endl;//4cout<<sizeof(B1)<<endl;//12cout<<sizeof(DD)<<endl;//24B1 b1;long** p;//定义指针的指针cout<<&b1<<endl;cout<<&b1.bb_<<endl;cout<<&b1.b_<<endl;p=(long**)&b1;//指向b1 对象,看图:所以这里就把b1 的地址转换成指针的指针//p[0];// p[0] 就是图 vbptr,指向vbtlcout<<p[0][0]<<endl;//0cout<<p[0][1]<<endl;//8 //打印结果与图相同  符合预期  return 0;}


cout<<&dd<<endl;
cout<<&dd.bb_<<endl;
cout<<&dd.b1_<<endl;
cout<<&dd.b2_<<endl;

cout<<&dd.dd_<<endl;

dd对象的内存模型图(不忍直视)


#include <iostream>using namespace std;class BB{public:int bb_;};class B1:virtual public BB{public:int b1_;};class B2:virtual public BB{public:int b2_;};class DD:public B1,public B2{public:int dd_;};int main(void){cout<<sizeof(BB)<<endl;//4cout<<sizeof(B1)<<endl;//12cout<<sizeof(DD)<<endl;//24B1 b1;long** p;//定义指针的指针cout<<&b1<<endl;cout<<&b1.bb_<<endl;cout<<&b1.b1_<<endl;p=(long**)&b1;//指向b1 对象,看图:所以这里就把b1 的地址转换成指针的指针//p[0];// p[0] 就是图 vbptr,指向vbtlcout<<p[0][0]<<endl;//0cout<<p[0][1]<<endl;//8 //打印结果与图相同  符合预期cout<<"====="<<endl;DD dd;cout<<&dd<<endl;cout<<&dd.bb_<<endl;cout<<&dd.b1_<<endl;cout<<&dd.b2_<<endl;cout<<&dd.dd_<<endl;p=(long**)ⅆcout<<p[0][0]<<endl;cout<<p[0][1]<<endl;cout<<p[2][0]<<endl;cout<<p[2][1]<<endl;return 0;}

打印结构0 20 0 12 符合预期

virtual 实质上的,事实上的,存在,共享,间接。基类对象放在最后的位置。

编译时刻已经决定了内存模型。

BB* pp;

pp=&d;

pp->bb_;//通过简介访问,这需要运行时支持。

通常都将虚基类部分成员 放在类对象的末尾。如果虚基类指针指向派生类对象, 运行时会调正基类指针的地址。到虚基类表中寻找偏移地址。需要运行时支持。

0 0