2011-04-11 103 views
1

伙计。我已经阅读了关于内联和虚函数之间的交互的几个线程。在大多数情况下,编译器不会将其视为内联。但是,当非虚拟内联成员函数调用虚函数时,该原则是否适用于该场景?说:内联和虚拟

class ABC{ 
public: 
    void callVirtual(){IAmVitrual();} 
protected: 
    virtual void IAmVirtual(); 
}; 

回答

2

什么原理?我期望编译器生成对虚函数的调用。该调用(实际上是跳转到函数指针)可以内联,但函数不是。

虚拟函数本身不是inline,并且不调用内联所需的限定条件,即使它是内联的,也不能内联。

0

你的情况callVirtual()将被内联。任何非虚函数都可以作为inline的一个很好的候选(显然最后的决定是编译器)。

0

虚拟函数必须在虚拟方法表中查找,因此编译器不能简单地将它们移动到内联。这通常是运行时查找。然而,内联函数可能会调用虚函数,编译器可以将该调用(代码在VMT中查找调用)内联。

2

虚拟函数的重点在于编译器通常不知道运行时需要哪个派生类实现,或者即使额外派生类将从共享库动态加载。所以,一般来说,内联是不可能的。编译器可以内联的一种情况是,它恰好知道它处理的是哪种类型,因为它可以在代码中看到具体类型,并且不久之后 - 类型没有改变的机会 - 看到调用虚拟功能。即使如此,它不是要求试图优化或内联,它只是唯一的情况下,甚至有可能。

除非事件探查器证明虚拟通话正在扼杀你,否则你不应该试图与之对抗。然后,首先尝试对一堆操作进行分组,以便一个虚拟呼叫可以为您做更多工作。如果虚拟调度仍然太慢,考虑维护某种区分的联合:它的灵活性和可扩展性要低得多,但可以避免虚函数调用开销并允许内联。

假设你真的需要动态分派:一些程序员和系统过度使用虚拟功能,仅仅是因为OO是20年前的事情,或者他们已经使用了像Java这样的OO语言。 C++有编译时多态机制的丰富选择,包括template