首页 > 解决方案 > 使用带有 Final 关键字的虚函数

问题描述

我有一个关于在 C++ 中使用关键字 final 的问题。据我了解,虚函数是在基类中声明的成员函数,预计会在派生类中被覆盖。通过动态绑定,将调用适当的方法,具体取决于负责调用的对象的类型。但是,为了防止基类中的成员函数在任何派生类中被覆盖,我们将使用 final 关键字。

void startEngine() final;// Compile error!
virtual void startEngine() final; //No error

为什么我们使用“final”来防止基类中的成员函数在派生类中被覆盖,同时我们仍然必须一起使用关键字VIRTUAL(允许覆盖)。

我试图删除虚拟这个词,但我得到一个编译错误:“非虚拟函数不能用'final'修饰符声明”

标签: c++virtual-functions

解决方案


首先,我们只有在函数可以被覆盖的情况下才能停止覆盖。所以final只对虚函数有意义。

尽管如此,final应用于单个类的虚函数可能看起来毫无意义。但是,如果您考虑更复杂的层次结构,事情会发生变化:

class Parent
{
public:
    virtual ~Parent() = default;
    virtual void f();
};
class Child : public Parent
{
public:
    void f() final; // f IS virtual already...
};
class GrandChild : public Child
{
    // cannot override f any more – while Child still could!
};

此外,请考虑以下事项:

class Base
{
public:
    virtual ~Base() = default;
    void f(); // non-virtual! (i. e. cannot be overridden)
};
class Derived : public Base
{
public:
    void f(); // does not override, but HIDEs Base::f!!!
};

同时声明Base::fvirtual 和 final 也可以防止隐藏(但不会过度加载)。

Base实际上,如果它本身已经从另一个多态类继承,那么这种情况还是很有意义的。如果不是并且Base不打算被继承,我根本不会引入任何虚拟函数(虚拟函数调用比普通函数调用更昂贵!)。如果那时用户仍然继承并隐藏了一个功能——好吧,他自己的责任......


推荐阅读