Today I was pretty happy when I learned that C++11 now finally knowns the final
keyword. With it you can easily define a whole class as final and even single virtual methods. But I wonder why this is not possible for non-virtual methods? Let's take this example:
class A {
public:
void m1() { cout << "A::m1" << endl; };
virtual void m2() { cout << "A::m2" << endl; };
};
class B : public A {
public:
void m1() { cout << "B::m1" << endl; };
virtual void m2() { cout << "B::m2" << endl; };
};
Here I can easily prevent B
from overriding the virtual m2
by declaring A::m2
as final. I would like to do the same with A::m1
so B
can't hide A:m1
with it's own implementation of the method. but the compiler doesn't accept the final
keyword without virtual
. And I wonder if there is a reason why C++11 doesn't allow this and if I misunderstood something completely. In my opinion it makes perfectly sense to define a non-virtual method as final because I didn't declare it as virtual because I don't want others to override/hide it anyway (Which I can now enforce with final
but unfortunately only for virtual methods...)
I like class designs where everything except abstract methods are final. It looks like this means I have to declare all methods as virtual
now to be able to do that. Is that a good idea or are there reasons against it? For older C++ versions I often read that is a bad idea to declare all methods as virtual. Or maybe there is a better way to prevent hiding non-virtual methods?
According to the C++11 standard, you are explicitly not allowed to do so for functions. The relevant passage is under § 9.2/8:
A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).
A virt-specifier includes final
and override
.
My guess is that they thought that these specifiers didn't make sense to be used in non-virtual functions since non-virtual functions are final
by default and they are the "final overrider" as the standard states in other sections.
It looks like this means I have to declare all methods as virtual now to be able to do that. Is that a good idea or are there reasons against it?
I recommend against it -- as having virtual functions has different effects on the code which you may not want. For example, the class will now have to keep a vtable and lose its POD status. Overall it seems like a bad move if you just want to use the final
keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With