在Nicolai Josuttis的CppCon演讲中(参见此处从34:10开始),他对使用说明符virtual
,override
和final
的建议之一是将所有函数标记为虚(对于多态类)或不标记它们(对于标准类)。
他这样做的理由是,它允许您编写不能被覆盖或隐藏的函数,通过在基类中指定这些函数为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++语言都不需要编译器内联展开函数调用。