虚拟继承、虚函数学习总结【Z】

虚拟继承、虚函数学习总结

 

 

 

一、虚函数。

其实是比较简单的,它的存在就是为了给子类继承,并且提供多个接口,所谓多个接口,就是多态性,它的主要特点就是父类的指针可以指向子类的对象,这样的话,在继承上会有好处。例如,某个父类有多个子类,在不知道会调用哪一个子类对象的情况下,可以定义一个父类的指针 f ,这样就实现了所谓的“接口”功能,在知道了要使用哪一个子类的时候,就直接把父类的指针 f 指向那个子类的对象,以后的操作都是采用父类的指针 f ,这样显然就有优点了,可以把对子类的操作封装起来,跟它使用哪一个子类没有关系了,因为在被封装起来的操作里面操作的对象是父类的指针 f ,然后这些被封装的操作就提供了一个“接口”,要用哪一个类的对象,就把那一个类对象的地址给父类的指针 f

二、虚函数非虚拟继承

CSDN 的博客上有一篇文章《 C++ 虚函数表解析》,作者:陈皓

网址: http://blog.csdn.net/haoel/archive/2007/12/18/1948051.aspx

说的是虚函数在内存中的格局,讲得很好理解。通过 vs2005 调试查看内存也是一样的。就是虚函数表。

三、虚拟继承。

CSDN 的博客上有一篇文章《 C++ 对象内存布局》,作者:陈皓

网址 http://blog.csdn.net/haoel/archive/2008/10/15/3081328.aspx

里面讲述了 c++ 虚函数的各种继承的内存布局,讲得非常详细,大部分的内容都很容易看懂,但是在 讲解虚拟继承上还有一点不足,就是虚函数的虚拟继承漏了一点内容,虚基函数表(vbtbl) 的相关内容。

另一篇文章写得很好,也是CSDN 博客上的,《 c++ 虚继承对象的内存布局

网址: http://blog.csdn.net/BlueDog/archive/2009/10/22/4711169.aspx

在《 C++ 对象内存布局》有一个名词叫做“钻石型虚拟多重继承”,之前不知道该怎么称呼这种继承,画成图,它们的形状就像棱形,一个基类产生两个子类,两个子类又同时被另一个“孙类”虚拟继承,最简单的虚拟继承就是这样子。

1、               没有涉及虚函数的虚拟继承。如果不管内部如何实现,简单的说就是“孙类”只拷贝一次基类,如果涉及到内存布局,那就必须通过 debug ,查看执行时的内存, c++ 虚继承对象的内存布局 》说到了这一点。通过内存查看“孙类”对象的地址,这个地址就相当于有虚函数的虚拟继承的“ Virtual Base Class Table ”简称“ VBTBL ”,当然名称可能有点问题,因为它只是包含用来寻找虚基类表的偏移值,而不是虚基类表的指针。在没有虚函数的情况下,它保存的内容同样有两项(因为只有一个基类),第一项为 0 ,因为没有虚函数,第二项为本地址相对于基类的偏移值。从“孙类”的内存中发现,基类的内容放在在最后面,这也跟有虚函数的时候一样。可能是为了跟有虚函数的时候统一,格式是一样的,这样的话,在没有虚函数的时候,有些是没有用的,如 B 子类也有个类似于“ VBTBL ”的东西,如果没有理解错的话,它应该是没用的,访问基类的时候用不着它。在查看内存的时候还发现了一些现象,内存里面没有函数的地址,只有变量空间,这个大概就是非虚函数跟虚函数的不同吧。通过查看内存可以很好的理解底层的东西。

2、               含有虚函数的虚拟继承。这就涉及到了虚函数表、虚基类、 VBTBL c++ 虚继承对象的内存布局 》里面说得很详细,那个“孙”类对象的内存结构图看起来非常的明确,我在 vs2005 里面查看,完全一样。

3、               总结:有虚拟继承的“孙”类的对象的内存格局是这样的,被虚拟继承的基类放在最后,子类按顺序放在基类的前面。子类的对象的内存格局,基类也是放在最后。虚拟继承的每一个类都有“ VBTBL ”之类的东西。


你可能感兴趣的:(C++,c,.net,C#,F#)