编译器是否需要在基类中内联虚函数和final函数?

  • 本文关键字:函数 final 是否 基类 编译器 c++
  • 更新时间 :
  • 英文 :


在Nicolai Josuttis的CppCon演讲中(参见此处从34:10开始),他对使用说明符virtual,overridefinal的建议之一是将所有函数标记为虚(对于多态类)或不标记它们(对于标准类)。

他这样做的理由是,它允许您编写不能被覆盖或隐藏的函数,通过在基类中指定这些函数为virtual-final。他指出,编译器可以直接内联函数,因为它能够推断出它实际上不是虚函数。这是一个有趣的建议,因为现在基类中的每个函数都意味着一些特定的东西,这取决于您使用的说明符:必须被覆盖,可以被覆盖,或者不能被覆盖。它还回避了一个问题,如果您的派生类可以在没有多态性的情况下调用,那么为什么要使其具有多态性呢?

因为这看起来是可行的,而演讲中的一些听众似乎不同意这个建议,所以我写了一个简单的程序来测试它(见这里)。clang似乎能够内联函数,而对于g++,doProcedure()函数无论如何都在虚函数表中结束。编译器是否需要内联这些类型的函数,或者当你这样做时是否会有性能损失?

测试的基本大纲如下所示,但我担心它可能太简单而掩盖了问题。

class Base
{
public:
virtual ~Base() = default;

virtual void doProcedure() const final  // Cannot be overridden
{
preProcess();
process();
postProcess();
}
protected:
virtual void preProcess() const;        // Can be overridden
virtual void process() const = 0;       // Must be overridden
virtual void postProcess() const;       // Can be overridden
};
class Derived : public Base
{
public:
virtual void process() const override;
// error: virtual function 'virtual void Derived::doProcedure() const' overriding final function
// void doProcedure() const {}
};

编译器是否需要内联函数…

。在任何情况下,c++语言都不需要编译器内联展开函数调用。

最新更新