class Z{ char zz[1];//34--48 , 34表示C::A::Z::zz的地址 ,C的地址从30开始存放虚表.. ,48表示C::B::Z::zz的地址.. int z;//38--4cpublic: Z():z(0){}};
class A:public Z{ char z[1];//3c int a;//40public: A():a(1){} virtual void Af()//30 -vf {
}};class B:public Z{ char z[1];//50 int b;//54public: B ():b(2){} virtual void Bf()//44 -vf {
}};
class C:public A,public B{ char z[1];//58 int c;//5cpublic: C():c(3){} virtual void Cf() {
} virtual void Af() {
}};
对于以上代码...在VS9(Dbg模式)下分析..
发现Z空间8字节..A空间20字节..B空间20字节...C空间48字节(非虚继承)...
A和B都有虚表指针... C继承了A和B...并且覆盖了Af...
在A的对象中...依次排列了A和B及C自身的数据...
A开始处存在虚表Vftb指向一个地址数组..存放了跳转Af和Cf的代码(jmp C::Af 导致覆盖,就实现了所谓的多态机制,由此导致调用虚函数时,事实上会有两次跳转...这就是所谓的虚函数代价及安全问题吧o(╯□╰)o..)..后面是“A..Z”的数据,A“自己”的数据...
...在C.A后面存放了B的对象...B的开始也是一个Vftb当然存放了B::Bf的地址(跳转代码地址)..以及“B..Z”的数据,B“自己”的数据...
...在C.B后面就是C自己的8字节数据..
事实上 在虚表中存放虚函数外还有type_info::`RTTI Complete Object Locator'(由"RTTI Type Descriptor"和"RTTI Class Hierarchy Descriptor"两部分组成,"RTTI Class Hierarchy Descriptor"包含一个"RTTI Base Array",这个Array包含有所有类的直接父类),type_info::`vector deleting destructor' 然后以0结束..这样为在使用dynamic_cast的转换提供类型信息...
可以参考文章:
http://blog.163.com/ecy_fu/blog/static/44451262009112410495582/
http://blog.csdn.net/haoel/archive/2008/10/19/3081328.aspx
http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html