如果我这样做:
Dog dog; //class with virtual methods
Cat cat; //class from same base as Dog
dog.eat(); //call virtual method
cat.eat(); //call virtual method
然后eat()s将是正常的方法调用,并且不需要v表 - 正确吗? 我可以假设它与非虚方法运行相同吗?
(是的,我知道编译器如何处理虚函数不符合标准 - 我想知道大多数编译器的作用)
答案 0 :(得分:4)
当您使用object.member
时 - 您没有取消引用指针,因此对virtual
方法没有影响。只有当你的指针可以是多态的并且使用动态调度时,Virtual
才会生效。
例如:
Cat cat;
Animal *cat2 = &cat;
cat.eat(); // direct call
//... a lot of other code and function calls that pass cat2 around, to avoid optimization
cat2->eat(); // dynamic dispatch
每次评论修改
答案 1 :(得分:2)
如果分析显示大多数时间都使用某种类型,Visual Studio可以将虚拟调用优化为直接调用。
虚拟来电投机 - 如果是 虚拟呼叫,或通过其他呼叫 函数指针,经常以a为目标 某些功能,配置文件引导 优化可以插入一个 有条件执行的直接电话 经常有针对性的功能,和 直接调用可以内联。
请参阅MSDN上的Profile Guided Optimization。
定期“虚拟化”(即其他答案所暗示的内容)可以在不分析应用程序的情况下完成,并且很常见。
GCC会自动启用此优化,但具体标志为 -fdevirtualize :
尝试将呼叫转换为虚拟 用于指导呼叫的功能。这是 在一个程序和 在程序上作为间接的一部分 内联(-findirect-inlining)和 过程间常数传播 (-fipa-CP)。在-O2级启用 -O3,-Os。
答案 2 :(得分:1)
如果在编译时已知静态类型,则无需使用vtable作为无论如何都要调用的函数。
大多数编译器都会看到这一点。
答案 3 :(得分:1)
我会说是的,大多数编译器都会进行此优化。如果您已经分析过并且它确实很重要,那么唯一可以确定的方法是检查生成的反汇编。