我理解的虚函数 原文地址:http://blog.chinaunix.net/uid-10780339-id-3247347.html
先列出问题。 1. c++中的关键词角度 Virtual 函数,纯虚函数,虚继承 。 2. 面向c++对象模型角度 看待虚函数 3. 虚函数的使用角度 结合ctor ,dtor等等 4. 高级主题,简要说明虚函数的优点、缺点 5.高级主题,请举例说明虚函数性能低的情形,并给出解决方案。 这里,我的回答是: 1. c++中的关键词角度 Virtual 函数(多态的基础),纯虚函数(对应类为抽象类),虚继承 (使用于多重继承对应父类为虚基类)。 2. 面向c++对象模型角度 看待虚函数 首先要懂虚表,(基础是分开一般函数(没有使用virtual关键词修饰的)的布局,还有知道dtor位于虚表) 在不同的继承层次(线性,扇形,钻石型)知道,虚表的布局。 还有使用了多态的函数如何转换成 c语言 (我理解:先找到虚表,然后找到对应函数指针) 3. 虚函数的使用角度 ctor为什么不能够调用虚函数(我理解:所有的子类成员还没有初始化,此时访问时机不对。) dtor为什么要设置为虚函数(调用子类dtor一次,就逐层销毁了所有(父类的,子类的)资源 ) 4. 高级主题,简要说明虚函数的优点、缺点(答案详细参考引用文档1,2) 优点:我理解,就是多态 缺点:这里多说点 a. 比起编译时就确定地址的同类功能的函数调用, 动态连编时有效率损失. b. 从指令级别讲, (1.虚函数的不确定性,会让编译器的 指令预测(或者说流水线技术)失效(详细参考) (2. 多了几条汇编指令(运行时得到对应类的函数的地址) (3. 编译器不能内联优化(仅在用父类引用或者指针调用时,不能内联) 5. 高级主题,请举例说明虚函数性能低的情形,并给出解决方案。(答案详细参考引用文档1,3) 当虚函数位于多层循环嵌套的核心部分时,这种情况更严重。还有另外一种性能下降显著的情况:当一系列虚函数频繁被调用时,我们不得不支付程序多次穿过“虚边界”的消耗。 解决方法很简单:把抽象提高到更高层即可。总的思路是不要让程序频繁在“虚-虚”或者“虚-非虚”之间切换。抽象提高后,把一系列虚函数或者循环中的虚函数都转移到更高一层,大大减低了切换的次数。 更多的关于虚函数的效率 详细点,效率有损失,数量级到底有多少,曾经有网友测试,1亿次系统调用会损失约1s,我个人觉得有点微不足道哈。但是这个测试案例不一定有代表性。 a. 虚函数调用效率和继承层数无关; b. 其实虚函数还是挺快的。虚函数的效率到底低不低和实际要调用的函数的耗时有关,当函数本身的的耗时越长,则虚函数的影响则越小。 c. 如果真的要完全移除虚函数,那么如果要实现运行时多态,则要用到函数指针,据上面的分析,函数指针基本具有虚函数的所有缼点(要传递函数指针,同样无法内联,同样影响流水线),且函数指针会使代码混乱。 补充: 幻の上帝 网友 提出使用 CRTP模式 解决效率问题。 shanehan 网友提出 使用 boost::bind boost::function来替代虚函数。 参考文档: 1. c++ 虚函数机制效率问题(关于流水线) <http://blog.csdn.net/metalkittie/article/details/3281916> 2. C++中虚函数(virtual function)到底有多慢 <http://blog.csdn.net/hengyunabc/article/details/7461919> 3. 【C++】虚函数的性能和vtable的细节——《C++游戏编程》读书笔记1 < ... 2a7f15b21bba55.html> 4.[C++虚函数系列1]如何使用CRTP模式解决虚函数的效率损失问题? ( http://blog.chinaunix.net/uid-9605822-id-2000053.html
阅读(1385) | 评论(0) | 转发(0) |