王朝网络
分享
 
 
 

C++ 内存布局(二) 虚继承 ---Empty virtual base classs (空虚基类)

王朝c/c++·作者佚名  2006-04-10
宽屏版  字体: |||超大  

上一次只是给出一个代码http://blog.csdn.net/OpenHero/archive/2006/04/02/648005.aspx,和运行过程中的内存位置,现在具体的按照步骤分析一下C++中虚拟继承中的情况,

由于C++ stand(C++ 标准委员会) 并没有规定具体实现的办法,各个编译器厂商可能都采用不同的实现方法,

或许在不同的年代使用的方法也不相同,有可能就会得到不同的结果,这里,我采用VC7.1作为调试工具,由潜

入深的一步步分析C++ 虚继承中的内存布局;

这一部分由Empty virtual base calss (空虚基类:空的calss)入手,查看VC7.1中是如何实现虚拟继承的.

下面给出测试的代码:

一,菱形的继承模式

class A

{ };

class B : virtual public A

{

};

class C : virtual public A

{

};

class D : public C, public B

{

};

int _tmain(int argc, _TCHAR* argv[])

{

A a;

B b;

C c;

D d;

int *pd = (int*)&d;

int *pd_c = (int*)(C*)(&d);

int *pd_b = (int*)(B*)(&d);

int *pd_a = (int*)(A*)(&d);

cout<< sizeof(a) << endl;

cout<< sizeof(b) << endl;

cout<< sizeof(c) << endl;

cout<< sizeof(d) << endl;

cout<< pd << endl;

cout<< pd_c << endl;

cout<< pd_b << endl;

cout<< pd_a << endl;

return 0;

}

有人会问,

class A

{ };

A a, 其中的a会有大小嘛?当然,a里面什么都没有,姑且就认为它是空的吧,但是,编译器如何才能记住a,而又

是空?你能想到一种实现的方法嘛?所以,编译器为了记住空的a,在a的内部放入了一个char的标记,作为它的

唯一标识,这样编译器才能认识那个a. 如果你有兴趣,你可以尝试定义A a,b; 然后你看看a和b是否是一

样的?现阶段来说,应该是不一样的,或许以后谁会发明新的实现方式,那个时候或许是一样也有可能了。

现在让我们看看上面程序的输出情况,如下:

1

4

4

8

0012FEAC

0012FEAC

0012FEB0

0012FEB4

这里我先不对上面的输出做出解释,或许你看了这样的输出会有疑惑,是不是和你想象的不一样?带着疑问

继续往下面看。

下面我再给出两段代码,同时给出他们各自的输出,然后再对这些输出做出解释:

二,六边形(菱形一)

class A

{ };

class B : virtual public A

{

};

class C : virtual public A

{

};

class D : /*virtual */public B

{

};

class E : /*virtual */public C

{

};

class F : public E, public D

{

};

int _tmain(int argc, _TCHAR* argv[])

{

A a;

B b;

C c;

D d;

E e;

F f;

int *pf = (int*)&f;

int *pf_e = (int*)(E*)(&f);

int *pf_d = (int*)(D*)(&f);

int *pf_c = (int*)(C*)(&f);

int *pf_b = (int*)(B*)(&f);

int *pf_a = (int*)(A*)(&f);

cout<< sizeof(a) << endl;

cout<< sizeof(b) << endl;

cout<< sizeof(c) << endl;

cout<< sizeof(d) << endl;

cout<< sizeof(f) << endl;

cout<< pf << endl;

cout<< pf_e << endl;

cout<< pf_d << endl;

cout<< pf_c << endl;

cout<< pf_b << endl;

cout<< pf_a << endl;

return 0;

}

输出结果:

1

4

4

4

4

8

0012FE94

0012FE94

0012FE98

0012FE94

0012FE98

0012FE9C

三,六边形(菱形二)

class A

{ };

class B : virtual public A

{

};

class C : virtual public A

{

};

class D : virtual public B

{

};

class E : virtual public C

{

};

class F : public E, public D

{

};

int _tmain(int argc, _TCHAR* argv[])

{

A a;

B b;

C c;

D d;

E e;

F f;

int *pf = (int*)&f;

int *pf_e = (int*)(E*)(&f);

int *pf_d = (int*)(D*)(&f);

int *pf_c = (int*)(C*)(&f);

int *pf_b = (int*)(B*)(&f);

int *pf_a = (int*)(A*)(&f);

cout<< sizeof(a) << endl;

cout<< sizeof(b) << endl;

cout<< sizeof(c) << endl;

cout<< sizeof(d) << endl;

cout<< sizeof(e) << endl;

cout<< sizeof(f) << endl;

cout<< pf << endl;

cout<< pf_e << endl;

cout<< pf_d << endl;

cout<< pf_c << endl;

cout<< pf_b << endl;

cout<< pf_a << endl;

return 0;

}

输出结果:

1

4

4

8

8

16

0012FE84

0012FE84

0012FE88

0012FE8C

0012FE90

0012FE8C

下面对其中的一,二做分析,三是一个有趣的现象,你可以考虑考虑:)

可以看到,只要有virtual的地方,都多出4个字节,用来干嘛?

在VC的编译器中,采用了virtual base calss pointer的方式来实现虚继承,从而保证子类回溯到基类的时

候只存在一个实体。多出来的4个字节就是用来存放各自的指向virtual base class 的地址的。

你可能又要问,a的大小为1,b,c……的大小只是4个4个增加,考虑内存对其,那不是会更大吗?

看到前面提到的一个问题了吗?

编译器只是为了记住a的时候才把a标示出来,如果知道a是空的,它既然有了子类,子类表示出来的时候,

当然基类就存在其中了:)

你可能又问? 那为什么不把子类也表示为1,不就行了吗?当然不行,就像上面提到的,因为是为了实现虚

继承的菱形一样的继承样式,在子类中只存在基类一个实体,所以,就才用了指针的方式,而不是把整个实

体放到子类的内存中。

在以后的内容中,会不断添加参数,函数,虚函数,分析虚继承中内存的分布。

声明:如果有网站转载,请把出处和连接加入到网页上,谢谢,咱,熬夜很困阿~~~

ps:太困,眼睛都睁不开了~~~~不行了,要睡觉了~~~~ 难免有打错的地方,请原谅

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有