C++';最终';关于类设计的方法注释承诺? 我知道C++中的最终的< /Cord>方法注释(因为C++ 11)从语言的角度来看。 class Base { virtual void method(); }; class Locked : public Base { virtual void method() final; };

C++';最终';关于类设计的方法注释承诺? 我知道C++中的最终的< /Cord>方法注释(因为C++ 11)从语言的角度来看。 class Base { virtual void method(); }; class Locked : public Base { virtual void method() final; };,c++,oop,c++11,C++,Oop,C++11,从Locked派生的任何类都不能再重写method 但是,从面向对象的角度来看,它对API和契约有何说明?如前所述,作为Locked课程的作者,关于现在整个课程的设计,我必须知道什么,我承诺什么 例如:我可以想象,通过使用final注释,我说的是“此方法行为不会改变”。但是如果我调用method()中的其他方法呢?如果它们可以被推翻,我怎么能保证呢?所以,用final注释是否意味着,严格地说,从面向对象的角度来看,我不能在该方法中使用其他可重写的方法?或其他设计约束?通常,您应该使用final关

Locked
派生的任何类都不能再重写
method

但是,从面向对象的角度来看,它对API和契约有何说明?如前所述,作为
Locked
课程的作者,关于现在整个课程的设计,我必须知道什么,我承诺什么


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

通常,您应该使用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();
}
#包括
使用名称空间std;
福班{
公众:
虚拟整型条()final{
foobar();
}

从OO理论的角度来看,虚拟void foobar(){cout(参见)派生类中被重写的方法不得违反基类中该方法集的任何约定。也就是说,从用户的角度来看,理想情况下,该方法在任何地方被重写与否都没有区别。因此,这就像是编译器的优化机会,或是想进一步子类化的程序员的提示。

说明了它所说的。你不能覆盖那个成员函数。就是这样。我不认为它说的是“行为没有改变”。我认为它说的是“你改变这个方法的实现方式是不安全的/不明智的”。有时方法会成为类基础结构的一部分,并且(如你所说)更改它们可能会对其他方法产生连锁反应。这一点很好。因此,
final
注释对LSP来说毫无意义,因为重写方法无论如何都不应该破坏契约。因此它只剩下
final
一个软件开发人员工具。我正确理解了你的意思吗?好的,但是考虑到类的完整契约通常是lly需要某种文档,可以将
final
视为LSP相关文档的缩写形式吗?不完全可以,如果您想象用户希望在某个软件上获取您的代码并将其用于其他目的,即使您坚持使用OOD,这并不意味着他会礼貌地不重写您的功能。我将
main
中对
a->foobar();
的调用更正为
a->bar();
。如果我错了,请将其反转。但是这样您的代码更有意义。对吗?是的,我复制了没有这两行的代码,而不是手动覆盖最后一行。应该是bar:)