将虚拟函数与最终关键字结合使用

Using Virtual Function with Final keyword

本文关键字:关键字 结合 虚拟 函数      更新时间:2023-10-16

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

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

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

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

首先,我们只能在可以覆盖函数的情况下停止覆盖函数。因此,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::f虚拟和最终的也可以防止隐藏(但不会过载(。

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