关于C++类的内存结构总结
2013-07-14 21:30
330 查看
一、真空类
class CNull { }; |
内存结构:
?? |
二、空类
class CNull2 { public: CNull2(){printf("Construct/n");} ~CNull2(){printf("Desctruct/n");} void Foo(){printf("Foo/n");} }; |
内存结构:
?? |
三、简单类
class COneMember { public: COneMember(int iValue = 0){m_iOne = iValue;}; private: int m_iOne; }; |
内存结构:
00 00 00 00 //m_iOne |
四、简单继承
class CTwoMember:public COneMember { private: int m_iTwo; }; |
内存结构:
00 00 00 00 //m_iOne CC CC CC CC //m_iTwo |
五、再继承
class CThreemember:public CTwoMember { public: CThreemember(int iValue=10) {m_iThree = iValue;}; private: int m_iThree; }; |
内存结构:
00 00 00 00 //m_iOne CC CC CC CC //m_iTwo 0A 00 00 00 //m_iThree |
六、多重继承
class ClassA { public: ClassA(int iValue=1){m_iA = iValue;}; private: int m_iA; }; class ClassB { public: ClassB(int iValue=2){m_iB = iValue;}; private: int m_iB; }; class ClassC { public: ClassC(int iValue=3){m_iC = iValue;}; private: int m_iC; }; class CComplex :public ClassA, public ClassB, public ClassC { public: CComplex(int iValue=4){m_iComplex = iValue;}; private: int m_iComplex; }; |
内存结构:
01 00 00 00 //A 02 00 00 00 //B 03 00 00 00 //C 04 00 00 00 //Complex |
七、复杂一些的继承
不写代码了,怕读者看了眼花,改画图。
长度:32
内存结构:
01 00 00 00 //A 02 00 00 00 //B 03 00 00 00 //C 04 00 00 00 //Complex 00 00 00 00 //OneMember CC CC CC CC //TwoMember 0A 00 00 00 //ThreeMember 05 00 00 00 //VeryComplex |
只要没涉及到“虚”(Virtual),我想没什么难点,不巧的是“虚”正是我们要研究的内容。
八、趁热打铁,看“虚继承”
class CTwoMember:virtual public COneMember { private: int m_iTwo; }; |
内存结构:
E8 2F 42 00 //指针,指向一个关于偏移量的数组,且称之虚基类偏移量表指针 CC CC CC CC // m_iTwo 00 00 00 00 // m_iOne(虚基类数据成员) |
九、“闭合”虚继承,看看效果
长度:24
内存结构:
14 30 42 00 //ClassB的虚基类偏移量表指针 02 00 00 00 //m_iB C4 2F 42 00 //ClassC的虚基类偏移量表指针 03 00 00 00 //m_iC 04 00 00 00 //m_iComplex 01 00 00 00 //m_iA |
十、看一下关于static成员
class CStaticNull { public: CStaticNull(){printf("Construct/n");} ~CStaticNull(){printf("Desctruct/n");} static void Foo(){printf("Foo/n");} static int m_iValue; }; |
内存结构:(同CNull2)
评注:可见static成员不会占用类的大小,static成员的存在区域为静态区,可认为它们是“全局”的,只是不提供全局的访问而已,这跟C的static其实没什么区别。
十一、带一个虚函数的空类
class CVirtualNull { public: CVirtualNull(){printf("Construct/n");} ~CVirtualNull(){printf("Desctruct/n");} virtual void Foo(){printf("Foo/n");} }; |
内存结构:
00 31 42 00 //指向虚函数表的指针(虚函数表后面简称“虚表”) 00423100:(虚表) 41 10 40 00 //指向虚函数Foo的指针 00401041: E9 78 02 00 00 E9 C3 03 … //函数Foo的内容(看不懂) |
十二、继承带虚函数的类
class CVirtualDerived : public CVirtualNull { public: CVirtualDerived(){m_iVD=0xFF;}; ~CVirtualDerived(){}; private: int m_iVD; }; |
内存结构:
3C 50 42 00 //虚表指针 FF 00 00 00 //m_iVD 0042503C:(虚表) 23 10 40 00 //指向虚函数Foo的指针,如果这时候创建一个CVirtualNull对象,会发现它的虚表的内容跟这个一样 |
十三、子类有新的虚函数
class CVirtualDerived: public CVirtualNull { public: CVirtualDerived(){m_iVD=0xFF;}; ~CVirtualDerived(){}; virtual void Foo2(){printf("Foo2/n");}; private: int m_iVD; }; |
内存结构:
24 61 42 00 //虚表指针 FF 00 00 00 //m_iVD 00426124:(虚表) 23 10 40 00 50 10 40 00 |
十四、当纯虚函数(pure function)出现时
class CPureVirtual { virtual void Foo() = 0; }; class CDerivePV : public CPureVirtual { void Foo(){printf("vd: Foo/n");}; }; |
内存结构:
CPureVirtual: (不可实例化) CDerivePV: 28 50 42 00 //虚表指针 00425028:(虚表) 5A 10 40 00 //指向Foo的函数指针 |
十五、虚函数类的多重继承
前面提到:(子类的虚表)不会因为增加了新的虚函数而多出另一张来,但如果有多重继承的话情况就不是这样了。下例中你将看到两张虚表。
大小:24
内存结构
F8 50 42 00 //虚表指针 01 00 00 00 //m_iA 02 00 00 00 //m_iB E8 50 42 00 //虚表指针 03 00 00 00 //m_iC 04 00 00 00 //m_iComplex 004250F8:(虚表) 5A 10 40 00 //FooA 55 10 40 00 //FooB 64 10 40 00 //FooComplex 004250E8:(虚表) 5F 10 40 00 //FooC |
转载地址:http://blog.csdn.net/guogangj/article/details/2036785
相关文章推荐
- C\C++编译器关于变量的内存分配顺序总结
- 面试中关于C++中的类,结构体,enum,字符变量等所占内存空间问题总结
- C++随记总结(1)----关于C++中的大小端、位段(惑位域)和内存对齐
- (总结)关于Linux的缓存内存 Cache Memory详解
- c++类对象内存结构
- C++类的存储及类对象内存结构(整理)
- Oracle 10g 内存结构体系学习总结
- 关于内存对齐以及通过偏移获得结构地址
- IOS开发(49)之关于 self与内存相关的用法总结
- 关于 内存对齐 && sizeof 的介绍 2 —— 结构体
- C++类对象内存结构
- C++类对应的内存结构
- Java内存结构学习总结
- 关于类包含虚函数的内存结构和虚函数调用
- 关于内存存储中的结构
- 关于内存的一小点总结
- C++冲刺(六)C++类对应的内存结构
- 关于java中的内存的理解总结
- C++类的存储及类对象内存结构
- 不错的总结-关于软件的三层结构