c++对象模型探讨
2012-10-08 11:39
141 查看
有一句经典的话,程序是写给人看的,顺便给机器执行。那么对于c++对象在内存中是怎么表示的。下面用win xp(32位) + vc++ 6.0对c++内存对象模型进行简明的探讨。
上面的类很简明,分别有两个虚函数一个int变量以及一个公有函数。那么请问一个A类的对象在内存的大小为多少即sizeof(A)?答案为8字节。因为一个int型变量为4字节,32位机加一个虚函数列表。那么继续看下面的单继承关系。
这里的sizeof(C)为多少?答案为12字节。在内存中即将两个结构叠合一起即m_ia+m_ic+vftables(虚函数列表),同时虚函数列表只有一张。
这里多继承的情况下sizeof(c)为多少?答案为20字节。可能为有疑问,因为m_ia+m_ib+m_ic+vftable_c(c的虚函数列表)应该为16字节,查看内存得知其实这里有两张虚函数列表,一个为B的,一个为A的。这里的答案可以自己上机得到,然后再思考为什么是这样。我们知道c++有几种类型的转换,static_cast,dynamic_cast,reinterpret_cast等。一般我们可以简单认为对于高精度向低精度转换时,只要将多余的截掉就ok啦。这种转换即保证指针的值不变,只改变所指向内存的大小,例如double
a ; int *p = &a 。但是对于这里的多继承关系,如上例c继承b和a。那么将c类对象指针转换为b类指针其值不变,那么转换为a呢?答案请自己上机验证。附上程序,调试过程以及图则略:
上面的类很简明,分别有两个虚函数一个int变量以及一个公有函数。那么请问一个A类的对象在内存的大小为多少即sizeof(A)?答案为8字节。因为一个int型变量为4字节,32位机加一个虚函数列表。那么继续看下面的单继承关系。
这里的sizeof(C)为多少?答案为12字节。在内存中即将两个结构叠合一起即m_ia+m_ic+vftables(虚函数列表),同时虚函数列表只有一张。
这里多继承的情况下sizeof(c)为多少?答案为20字节。可能为有疑问,因为m_ia+m_ib+m_ic+vftable_c(c的虚函数列表)应该为16字节,查看内存得知其实这里有两张虚函数列表,一个为B的,一个为A的。这里的答案可以自己上机得到,然后再思考为什么是这样。我们知道c++有几种类型的转换,static_cast,dynamic_cast,reinterpret_cast等。一般我们可以简单认为对于高精度向低精度转换时,只要将多余的截掉就ok啦。这种转换即保证指针的值不变,只改变所指向内存的大小,例如double
a ; int *p = &a 。但是对于这里的多继承关系,如上例c继承b和a。那么将c类对象指针转换为b类指针其值不变,那么转换为a呢?答案请自己上机验证。附上程序,调试过程以及图则略:
#include<stdio.h> #include<iostream> using namespace std; class A { public: A():m_ia(0) {} virtual void vfun0() ; virtual void vfunA1(); int m_ia ; void funA() ; } ; void A::vfun0() { cout<<" vfunA0 called "<<endl ; } void A::vfunA1() { cout<<" vfunA1 called "<<endl ; } void A::funA() { cout<<"funA called "<<endl ; } class B { public: B():m_ib(0) {} virtual void vfun0() ; virtual void vfunB1() ; int m_ib ; void funB() ; } ; void B::vfun0() { cout<<" vfunB0 called "<<endl ; } void B::vfunB1() { cout<<" vfunB1 called "<<endl ; } void B::funB() { cout<<"funB called "<<endl ; } class C : public B , public A{ public: C():m_ic(0) {} virtual void vfun0(); virtual void vfun1(); int m_ic ; }; void C::vfun0() { cout<<" vfunC0 called "<<endl ; } void C::vfun1() { cout<<" vfunC1 called "<<endl ; } int main () { A *pa , a ; B *pb ,b ; C c ; pa = reinterpret_cast<A*>(&c) ; printf("the pa :0x%p\n",pa); pa->vfun0(); pa->vfunA1(); printf("pa->vfunA1:%p\n",pa->vfunA1); printf("c.vfun1:%p\n",c.vfun1); pb = &c ; printf("the pb :0x%p\n",pb); pb->vfun0(); pb->vfunB1(); printf("c size:%d\n",sizeof(c)); c.vfun1(); printf("%d\n",sizeof(c)); return 0 ; }
相关文章推荐
- C++虚继承内存对象模型探讨
- [原创]C++虚继承内存对象模型探讨
- 深入探索C++对象模型一书中拷贝构造函数和NRV关系探讨
- C++虚继承内存对象模型探讨
- 深度探索c++对象模型之临时对象的探讨
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- 自己对C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- 深入探讨C++对象模型 之 站在对象模型的尖端
- C++对象模型——指向Member Function的指针 (Pointer-to-Member Functions)(第四章)
- C++对象模型之简述C++对象的内存布局
- C++对象模型(三):Program Transformation Semantics (程序转换语义学)
- C++虚函数、虚继承、对象内存模型
- C++对象模型3--无重写的单继承
- C++对象模型 第五章 构造、析构、拷贝语意学
- C++对象模型2--指针cout结果
- 读【深度探索C++对象模型】【下】
- 读深入C++对象模型的总结
- C++对象内存模型(高级)—多重继承与虚函数表(转)