人。我已经阅读了几个关于内联和虚拟共存在一个函数中的线程的线程。在大多数情况下,编译器不会将其视为内联。但是,当非虚拟内联成员函数调用虚函数时,原则是否适用于该场景?说:
class ABC{
public:
void callVirtual(){IAmVitrual();}
protected:
virtual void IAmVirtual();
};
答案 0 :(得分:2)
什么原理?我希望编译器生成对虚函数的调用。可以内联调用(实际上是跳转到函数指针),但IAmVirtual
函数不是。
虚函数本身不是inline
,并且即使它被内联,也不会调用它,因此无法内联。
答案 1 :(得分:2)
虚函数的重点在于编译器通常不知道在运行时需要哪个派生类实现,或者即使从共享库动态加载额外的派生类。所以,一般来说,内联是不可能的。编译器可以内联的一种情况是它确实知道它正在处理哪种类型,因为它可以在代码中看到具体的类型并且很快就会发生 - 不会有类型的变化 - 看到对虚拟功能的调用。即使这样,尝试优化或内联也不是 required ,它只是唯一可能的情况。
除非探查者证明虚拟呼叫会杀死你,否则你不应该试图解决这个问题。然后,首先尝试对一组操作进行分组,以便一个虚拟调用可以为您完成更多工作。如果虚拟调度仍然太慢,可以考虑维护某种有区别的联合:它的灵活性和干净可扩展性要低得多,但可以避免虚函数调用开销并允许内联。
所有这些都假设你真的需要动态调度:一些程序员和系统过度使用虚拟函数只是因为OO是20年前的东西,或者他们使用的是像OO这样的语言。 C ++有很多编译时多态机制,包括template
s。
答案 2 :(得分:0)
在您的情况下,callVirtual()
将被内联。任何非虚函数都可以成为inline
的良好候选者(显然最后的决定是编译器)。
答案 3 :(得分:0)
必须在虚拟方法表中查找虚函数,因此编译器不能简单地将它们移动到内联。这通常是运行时查找。然而,内联函数可以调用虚函数,编译器可以将该调用(用于在VMT中查找调用的代码)内联。