C++"最终"方法注释对类设计有什么承诺?

What does C++ 'final' method annotation promise about the class design?

本文关键字:什么 承诺 最终 方法 注释 C++      更新时间:2023-10-16

我知道c++中的final方法注释(从c++ 11开始)从语言的角度做了什么。

class Base {
    virtual void method();
};
class Locked : public Base {
    virtual void method() final;
};

Locked派生的类不能再覆盖method

但是从面向对象的角度来看,它对API和契约说了什么?对于Java, ,作为Locked的类作者,我必须意识到什么,关于整个类的设计现在,我承诺什么?

例如:我可以想象,通过用final注释,我说"这个方法的行为不会改变"。但是如果我调用method()内部的其他方法呢?如果它们可以被重写,我怎么能保证呢?那么,用final注释是否意味着,严格地说,从OOP的角度来看,我不能在该方法中使用其他可重写的方法?或者其他设计约束?

通常,您应该使用final关键字向用户提供确定性,即由于安全原因或任何其他要求,该函数不会发生覆盖行为,从而使您希望将类函数限制为final。

如果你使用任何其他方法,它们也应该被标记为final,除非它们操作的字段是私有的(你可以想象一些场景,默认行为修改私有字段,但你可以允许重写函数做其他事情)。

关键字本身只限制函数被覆盖,它不会神奇地知道函数不随类扩展基而改变的真正含义。

#include <iostream>
using namespace std;
class foo{
    public:
    virtual int bar() final{
        foobar();
    }
    virtual void foobar(){cout << "blah";}
};
class baz : public foo{
    public:
        void foobar() override {
            cout << " not blah";
        }
};
int main(){
    baz * a = new baz();
    a->bar();
}

例如,下面的代码将打印"not Blah"

从OO理论的角度来看(参见LSP),派生类中被重写的方法必须不违反基类中该方法设置的任何契约。也就是说,从用户的角度来看,理想情况下,方法是否在任何地方被覆盖都没有区别。因此,这就像是编译器的一个优化机会,或者是对可能想要进一步子类化的程序员的一个提示。