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