C++虚函数表汇总

来源:互联网 发布:淘宝客服基础知识 编辑:程序博客网 时间:2024/05/20 02:29
一般来说,对于开发者我们只需要知道虚函数的使用方法,以及虚函数表的存在即可。但面试时往往会遇到更细节的问题,比如让你实现一个虚函数机制,虽然不太实用,总归了解些底层知识也是件好事。但如果有人苦苦相逼一定要拿这个刷人,你就去骂他吧,你才是写编译器的,你们全家都是写编译器的。唉,我有些失态了...

1. 虚函数与虚函数表基本知识

这里有一篇介绍,只需看前两页,各种配图,很形象:http://dev.yesky.com/208/8061708.shtml

这篇文章则更精练,只需看第一段就好:http://blog.csdn.net/jiangnanyouzi/article/details/3720807

总的来说,每一个拥有virtual function的类实例化对象时,都会额外申请一块内存存储虚函数表存储所有虚函数地址,并在对象某个位置存储一个vptr指针指向该表起始地址。这个指针具体放在什么位置,虚函数表怎么组织,怎么索引各个虚函数,这些都是编译器在编译期间决定的,在不同编译环境下不见得相同。

 

2. 多态子类的调用顺序 -- 为什么不要在构造函数中调用虚函数

原因是,在子类的构造函数执行时,虚函数表还没有被子类覆盖,换句话说,此时调用的函数是当前类的函数,虚函数机制在构造函数中无法触发。其原因在于子类构造时各个初始化步骤的调用顺序:

全部推演过程见此:http://saturnman.blog.163.com/blog/static/557611201081421344244/

直接摘录构造顺序:

1.构造子类构造函数的参数

2.子类调用基类构造函数

3.基类设置vptr

4.基类初始化列表内容进行构造

5.基类函数体调用

6.子类设置vptr

7.子类初始化列表内容进行构造

8.子类构造函数体调用

(注意一点,初始化列表内的数据不按书写顺序,而是按类内部的定义顺序)

析构的顺序恰好相反,所以也不要在析构函数中调用虚函数,那样也是没有意义的。

 

3. 如何去验证虚函数表的存在

其实在第一个链接里已经有了示例程序。

如果你看不懂函数指针,请看这里:http://hi.baidu.com/homonia/blog/item/90b7a72c49c521ea8a1399e2.html

 

4. 为什么构造函数不能是虚函数

从设计理念上说,构造函数不需要是虚函数;从当前vptr的实现机制上说,无法实现虚的构造函数。

详细可见这里:http://www.diybl.com/course/3_program/c++/cppxl/2008320/105849.html

原文地址:http://hi.baidu.com/hehehehello/item/60b7390d29003bc32e4c6b8d

原创粉丝点击