虚拟继承解决二义性及数据冗余的原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟继承解决二义性及数据冗余的原理相关的知识,希望对你有一定的参考价值。
虚拟继承的原理虚拟继承解决数据冗余和二义性的奥秘就在于,它在继承之后并不会创造出两个基类成员给派生类各自继承,而是在派生类中记录两个偏移量,大小为从派生类中继承的基类成员的地址到真正的基类成员地址,而这个真正的成员,被放在最后一次继承的派生类(D类)的末尾。
![技术图片](https://s1.51cto.com/images/blog/202003/14/e35ff51ff96afa2075c8647795ab4577.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
如图所示,在不使用虚拟继承的前提下,各个类定义定义变量后我们可以看看他们各自所处的地址如下:
![技术图片](https://s1.51cto.com/images/blog/202003/14/455cb08006379635c0ea920f37a8c8bc.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
可以看出,A,B类继承的m_n处于不同的地址,是两个成员。而使用虚拟继承后他们所处地址的内容变成了如下:
![技术图片](https://s1.51cto.com/images/blog/202003/14/cc8314d0f31f15bbcff8bc813dee9e5c.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
可以看出,原本为值‘3’和‘4’的地方变成了两个偏移量,而我们调取这两个偏移量之后可以看到如下:
e8 d2 f5 00 :12(H)
![技术图片](https://s1.51cto.com/images/blog/202003/14/75bf12d802e982d111fe137835f0cc0f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
ac cb f5 00 :20(H)
![技术图片](https://s1.51cto.com/images/blog/202003/14/a01a0dd80e73a47cadb5362a5ebca3d6.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
而我们发现,从起始位置到下面04的位置(D类中的末尾),偏移字节正好是12和20。
其实,这里是通过B和C的两个指针,指向一张表,这两个指针叫做虚基表指针,这两个表叫虚基表,虚基表中存的偏移量,通过偏移量可以找到下面的A。
Ps:并不是所有派生类共用一分虚基表,每个派生类都有自己的表;
以上是关于虚拟继承解决二义性及数据冗余的原理的主要内容,如果未能解决你的问题,请参考以下文章