在C++中,我的理解是虚函数可以被内联,但通常会忽略内联提示。似乎内联的虚函数并没有太大意义。
是这样吗?
有人能给出一个内联虚函数有用的案例吗?
是这样吗?
有人能给出一个内联虚函数有用的案例吗?
virtual
属性既可以应用于函数本身,也可以应用于调用该函数的方法。有虚拟和非虚拟函数,还有对这些函数的虚拟和非虚拟调用。inline
属性。存在内联和非内联函数,以及对这些函数的内联和非内联的调用。virtual
和inline
-当应用于函数本身时不会冲突。它们只是没有理由和机会发生冲突。对于函数本身,inline
关键字所做的唯一修改就是修改该函数的一个定义规则:该函数可以在多个翻译单元中被定义(并且必须在使用它的每个翻译单元中都被定义)。而virtual
关键字所做的唯一修改就是使包含该函数的类成为多态。它对函数本身没有实际影响。virtual
和inline
关键字时,绝对没有问题。基础原则上不存在任何冲突。在C++语言中这是完全合法的。struct S {
virtual void foo();
};
inline void S::foo() // virtual inline function - OK, whatever
{
}
然而,当人们提出这个问题时,通常不是对函数本身的属性感兴趣,而是对调用该函数的特征感兴趣。
虚函数调用的定义特征是它在运行时被解析,这意味着真正的虚函数调用通常无法进行内联:
S *s = new SomeType;
s->foo(); // virtual call, in general case cannot be inlined
然而,如果调用本身不是虚函数(即使它调用了一个虚函数),那么内联就根本不是问题:
S *s = new SomeType;
s->S::foo(); // non-virtual call to a virtual function, can easily be inlined
当然,在某些情况下,优化编译器可能能够在编译时找出虚函数调用的目标,并内联甚至是这样的虚函数调用。在某些情况下很容易:
S ss;
ss.foo(); // formally a virtual call, but in practice it can easily be inlined
在某些情况下,这可能更加复杂,但仍然可行:
S *s = new S;
s->foo(); // virtual call, but a clever compiler might be able
// to figure out that it can be inlined
ss.foo();
形式上是一个虚函数调用呢? - Bellocss.foo()
有什么特殊或不同的地方。唯一忽略“动态类型”的调用是限定名称的调用。 - AnT stands with Russia-O0
开关在clang中可以得到相同的结果。无论如何,你能否给我一个标准的引用,证实你所说的内容? - Belloc在正常情况下,虚函数将通过指向函数的指针(包含在类的虚函数表中)来调用。因此,只有在编译器可以静态确定将调用该函数的实际类型时,即它必须是类X或继承自X的某些内容,才能在内联方式下生成虚函数调用。
内联虚函数的主要应用场景是在性能至关重要的情况下,并且已知一个类将经常以一种方式使用,使得编译器可以静态地确定实际类型(并且至少有一个目标编译器可以通过指针优化掉调用)。
inline
。 - Georg Fritzsche