内联虚函数

sky*_*oor 20 c++

在C++中,我的理解是可以内联虚函数,但通常会忽略内联提示.似乎内联虚函数没有太多意义.

是对的吗?

任何人都可以提供一个内联虚函数好的案例吗?

AnT*_*AnT 39

为了完全回答这个问题,我们需要理解,存在的属性是virtual独立地应用于函数本身以及对该函数的调用.有虚拟和非虚拟功能.有对这些功能的虚拟和非虚拟调用.

关于存在的属性也是如此inline.有iniline和non-inline函数.并且内联非内联调用这些函数.

这些属性 - virtual以及inline- 应用于函数本身时,不会发生冲突.他们根本没有理由也没有冲突的机会.inline对于函数本身,说明符唯一变化的是它修改了该函数的一个定义规则:该函数可以在多个转换单元中定义(并且必须在使用它的每个转换单元中定义它).唯一的virtual说明符更改是包含该函数的类变为多态.它对功能本身没有实际影响.

因此,有绝对的声明功能没有问题virtual,并inline在同一时间.冲突没有根据.它在C++语言中是完全合法的.

struct S {
  virtual void foo(); 
};

inline void S::foo() // virtual inline function - OK, whatever
{
}
Run Code Online (Sandbox Code Playgroud)

然而,当人们提出这个问题时,他们通常对函数本身的属性不感兴趣,而是对函数调用的特性感兴趣.

虚拟调用的定义特征是它在运行时被解析,这意味着通常无法内联真正的虚拟调用:

S *s = new SomeType;
s->foo(); // virtual call, in general case cannot be inlined
Run Code Online (Sandbox Code Playgroud)

但是,如果一个调用本身是非虚拟的(即使它转到虚函数),内联根本不是问题:

S *s = new SomeType;
s->S::foo(); // non-virtual call to a virtual function, can easily be inlined
Run Code Online (Sandbox Code Playgroud)

当然,在某些情况下,优化编译器可能能够在编译时找出虚拟调用的目标,并且甚至可以内联这样的虚拟调用.在某些情况下很容易:

S ss;
ss.foo(); // formally a virtual call, but in practice it can easily be inlined
Run Code Online (Sandbox Code Playgroud)

在某些情况下,它更复杂,但仍然可行:

S *s = new S;
s->foo(); // virtual call, but a clever compiler might be able
          // to figure out that it can be inlined
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 14

在正常情况下,将通过指向函数的指针调用虚函数(该函数包含在类'vtable中).在这种情况下,如果编译器可以静态地确定将调用该函数的实际类型,而不仅仅是它必须是X类或从X派生的东西,则只能内联生成虚函数调用.

内联虚函数的主要时间是有意义的,如果你有一个性能危急情况,并且知道一个类经常以允许编译器静态确定实际类型的方式使用(并且至少有一个目标编译器优化了通过指针调用).

  • @gf,不,它解决了内联虚函数的概念.即使没有inline关键字,在类体中声明的函数也会隐式声明为内联函数. (4认同)
  • 这个问题解决了关键字`inline`. (2认同)