5

I am aware what the final method annotation in C++ (since C++11) does from a language point-of-view.

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

Any class deriving from Locked can not override method anymore.

But what does it say about the API, the contract from an OOP point of view? As already asked for Java, what must I be aware of, as a class author of Locked, about the design of the whole class now, what do I promise?

For example: I could imagine that by annotating with final I am saying that "this methods behavior does not change". But what if I call other methods inside method()? If they can be overridden, how can I promise that? So, does annotating with final mean, I must not use other overridable methods inside that method, strictly speaking, from an OOP point-of-view? Or other design constraints?

Community
  • 1
  • 1
towi
  • 21,587
  • 28
  • 106
  • 187
  • 3
    It says what it says. You cannot override that member function. That's it. – juanchopanza Aug 22 '14 at 09:13
  • I don't see it as saying "the behaviour doesn't change". I see it as saying "it is not safe/sensible for you to change how this method is implemented". Sometimes methods become part of the class infrastructure and (as you say) changing them can have knock-on effects to other methods. – Galik Aug 22 '14 at 16:34

2 Answers2

5

Usually you should be using the final keyword to provide user with the certainty that no overwritten behavior for this function will occur for security reasons or any other requirements that make you want to restrict the class function to be final.

If you are using any other methods they should also be marked as final unless for instance the field on which they are operating are private ( you can imagine some scenarios in which default behavior modifies private fields but you can allow overwritten function to do something else as well).

The keyword itself ONLY restricts the function to be overwritten it wont magically know what does it really mean for the function not to change with classes extending base.

#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();
}

For example this code will print "not Blah"

towi
  • 21,587
  • 28
  • 106
  • 187
cerkiewny
  • 2,761
  • 18
  • 36
  • I corrected the call of `a->foobar();` in `main` to be `a->bar();`. Please reverse this if I was wrong. But this way your code makes more sense. Right? – towi Aug 22 '14 at 12:05
  • Yes, I have copied the code without the 2 lines, than manually overwritten the last one. it should be bar :) – cerkiewny Aug 22 '14 at 12:06
0

From OO theory point of view (see LSP) an overridden method in a derived class must not violate any contract of that method set in the base class. That is, from user's perspective, ideally there is no difference whether the method is overridden anywhere or not. So it's like an optimization opportunity for the compiler or a hint for programmers who might want to subclass further.

  • Good point. So, `final` annotation is meaningless wrt. to LSP, since an overriding method should not break a contract anyway. So it leaves `final` to just a software developers tool. Did I get your meaning correctly? Ok, but given that the full contract of a class usually requires some sort of documentation, can one see the `final `as an abbreviated form of some form of documentation regarding LSP? – towi Aug 22 '14 at 11:58
  • 1
    Not really, if you imagine the software on which the user wants to take your code and use it for other purpose even though you are sticking to OOD it doesn't mean he will politely not override your function. – cerkiewny Aug 22 '14 at 12:10