欢迎来到天天文库
浏览记录
ID:59257441
大小:382.50 KB
页数:16页
时间:2020-09-08
《(多重继承虚继承的内存布局).doc》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、1.多重继承、虚继承的内存空间布局对多重继承、虚继承的内存空间布局进行研究,循序渐进的进行处理,主要关注以下几点:1)偏移表2)虚表3)数据成员4)它们的位置5)它们的大小及内容6)它们间的关系。1.1单继承,无虚函数的情况单继承、无虚函数的情况是:1)基类的数据成员2)派生类新增的数据成员派生类的大小是基类数据成员和派生类新增数据成员大小之和。顺序是按照上面的基类、派生类的顺序进行布局。1.2单继承,有虚函数的情况单继承、有虚函数的情况:1)派生类的虚表指针2)基类的数据成员3)派生类新增的数据成员其中,派生类的虚表,是在基类的虚表基础之
2、上所作的修改,有可能是:1)对基类中虚函数地址的覆盖2)派生类中新增的虚函数地址1)只要有虚函数,就有虚表产生。2)虚表中条目的个数,是本类中虚函数的个数3)虚表中各条目的顺序,与类中声明(定义)的虚函数顺序一致1.3多重继承,无虚函数的情况多重继承、无虚函数的情况是:1)基类的数据成员2)基类的数据成员3)派生类新增的数据成员这里与1.1单继承,无虚函数的情况的差别是——可能存在多个基类。这里基类数据成员的排放,是按照继承的数据依次进行的。1.4多重继承,有虚函数的情况多重继承,有虚函数的情况是:1)基类的虚表指针2)基类的数据成员3)基
3、类的虚表指针4)基类的数据成员5)派生类新增的数据成员这里与1.2单继承,有虚函数的情况的差别是——虚表这里说基类的虚表指针,其实是不太恰当的,因为它们实际上是派生类虚表的一部分。也就说,派生类的虚表是由多个基类的虚表所构成的。不存在一个单一的派生类的虚表。派生类的虚表条目是在各基类的虚表基础之上修改所得,可能包括:1)对基类中虚函数的覆盖,会更新各基类虚表中的条目2)派生类中新增的虚函数地址,会追加到第一个继承的基类的虚表中至此,上面1.1单继承,无虚函数的情况1.2单继承,有虚函数的情况1.3多重继承,无虚函数的情况1.4多重继承,有虚
4、函数的情况是从单继承/多重继承,无/有虚函数的角度进行的梳理。下面将以菱形继承为主线,来进行梳理。(菱形继承中可能出现二义性,会逐步的引入虚继承,虚基类的概念)菱形继承(diamond-inheritance)1.5菱形继承,无虚函数的情况ClassA{};ClassB:publicA{};ClassC:publicA{};ClassD:publicB,publicC{};菱形继承,无虚函数的情况是:1)基类B的数据成员a)基类A的数据成员b)派生类B新增的数据成员2)基类C的数据成员a)基类A的数据成员b)派生类C新增的数据成员3)派生类
5、D新增的数据成员这里仍然是没有太大的变化,按照基类、派生类的顺序安放数据成员。1.6菱形继承,有虚函数的情况ClassA{};ClassB:publicA{};ClassC:publicA{};ClassD:publicB,publicC{};菱形继承,有虚函数的情况:1)基类B的虚表指针a)基类A的虚函数(未被覆盖的部分)b)基类B的虚函数(覆盖A的部分,新增的部分)c)派生类D的虚函数(新增的部分)2)基类B的数据成员a)基类A的数据成员b)派生类B新增的数据成员3)基类C的虚表指针a)基类A的函数(未被覆盖的部分)b)基类C的虚函数(
6、覆盖A的部分,新增的部分4)基类C的数据成员a)基类A的数据成员b)派生类C新增的数据成员5)派生类D新增的数据成员仍然要说一点,这里说基类的虚表指针,其实是不太合适的,它们是派生类的虚表的一部分,是派生类在基类的虚表基础之上所做修改而来的:1)如果派生类中的虚函数与基类中的形成覆盖,则派生类会对基类的虚表中相应条目做覆盖处理2)派生类中新增的虚函数地址,追加至第一个继承的基类虚表中。1.7菱形继承,无虚函数,为虚继承的情况在上面的1.5菱形继承,无虚函数的情况1.6菱形继承,有虚函数的情况中,最基类A,在内存空间中有多份拷贝。利用虚继承可
7、以解决,此时最基类A成为虚基类。所以,菱形继承,无虚函数,为虚继承的情况,也就是菱形继承,无虚函数,有虚基类的情况。虚继承的引入,使得虚基类在内存中仅存一份拷贝,同时带来的影响还有内存空间布局的变化。大概有:1)虚基类的数据成员在内存中的位置2)偏移表偏移表的存在,是因为——虚基类的单份存在,而虚基类A又被B,C所共享,所以对B,C而言,它们就各自需要确定A的所在位置。偏移表就是用于该问题。偏移表的数目,就是直接继承自虚基类的派生类的数目。现在来一一测试。在看到这些信息后,我们猜测其内存空间的布局:1)B的偏移表,在ecx处2)B的数据成员
8、,在ecx+4处3)C的偏移表,在ecx+8处4)C的数据成员,在ecx+0C处5)D的数据成员,在ecx+10处2)A的数据成员,在ecx+14处下面先对偏移表进行跟踪正是通过
此文档下载收益归作者所有