类型在编译时已知的虚方法

时间:2011-06-02 18:47:44

标签: c++ inheritance methods virtual

如果我这样做:

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表 - 正确吗? 我可以假设它与非虚方法运行相同吗?

(是的,我知道编译器如何处理虚函数不符合标准 - 我想知道大多数编译器的作用)

4 个答案:

答案 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。

来自GCC Optimize Options

答案 2 :(得分:1)

如果在编译时已知静态类型,则无需使用vtable作为无论如何都要调用的函数。

大多数编译器都会看到这一点。

答案 3 :(得分:1)

我会说是的,大多数编译器都会进行此优化。如果您已经分析过并且它确实很重要,那么唯一可以确定的方法是检查生成的反汇编。