虚拟继承、虚函数学习总结 一、虚函数。 其实是比较简单的,它的存在就是为了给子类继承,并且提供多个接口,所谓多个接口,就是多态性,它的主要特点就是父类的指针可以指向子类的对象,这样的话,在继承上会有好处。例如,某个父类有多个子类,在不知道会调用哪一个子类对象的情况下,可以定义一个父类的指针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”之类的东西。
网络上有很多的好文章,学习起来非常的快,虚函数的知识,前几天还没有涉及到底层的东西,理解也没有那么深刻,通过网络上查找高手的文章,再加上自己的验证,很多东西都理解了。查找资料很重要,如果没有资料可以看,自己不知道要搞多久才知道底层的知识原来是这样。关于这方面的书应该是《Inside the C++ Object Model》,只是才刚开始学,很多基础还要加强,另外时间也是个问题。 好像有一个观点:学了点知识,就要及时总结,这样才算学会了。大概就是这样子。作为一个菜鸟,有些内容的表达上,可能会有点问题。 JUST DO IT。。
2010.8.21更新: 发现这篇文章理解得太浅了,也表达得不够清晰,重写理解总结如下: http://www.cnblogs.com/cswuyg/archive/2010/08/20/1804113.html |
虚拟继承、虚函数学习总结
最新推荐文章于 2022-05-01 14:03:50 发布