上一次只是给出一个代码http://blog.csdn.net/OpenHero/archive/2006/04/02/648005.ASP x,和运行过程中的内存位置,现在具体的按照步骤分析一下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;
复制本页网址和标题,发送给你QQ/Msn的好友一起分享
上一篇:samba和openldap结合实战
下一篇:由于域安全组嵌套导致SPS访问控制群组和用户配置文件搜索失败