Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Some idle questions about override and final

51 views
Skip to first unread message

K. Frank

unread,
Apr 22, 2015, 12:15:33 PM4/22/15
to
Hello Group!

A couple of quick questions:

override:

If starting with a clean slate, would it have made
sense to make the use of override mandatory?

(I understand that making it mandatory would have
severely broken backward compatibility.)

That is:

struct A {
virtual void f();
virtual void g();
};

struct B : A {
void f() override; // remains legal with mandatory override
void g(); // not legal with mandatory override
};

(I like override -- state your intentions, make code more
readable, help catch errors -- but would have making it
mandatory have been going to far?)


final:

I understand that there is debate about whether using
final ever makes sense, but leaving that aside:

Would declaring a virtual function final in a base class
ever make sense? I.e.,

struct A {
virtual void f() final;
};

The only thing I can think of would be to force A to
be a "polymorphic" class, e.g., trigger RTTI, etc.,
but this seems pretty contrived.


Thanks for any insight.


K. Frank

Victor Bazarov

unread,
Apr 22, 2015, 12:44:19 PM4/22/15
to
On 4/22/2015 12:15 PM, K. Frank wrote:
> A couple of quick questions:
>
> override:
>
> If starting with a clean slate, would it have made
> sense to make the use of override mandatory?

"Would it *have made* sense"? Why subjunctive? Why not just "does it
make sense"?

Yes, it does make sense just as much as without it. I suppose you are
referring to a convention of some kind, or a coding standard... Those
are like religion. If I don't like your standards, I won't work for
your group. If I care to work for your group more than I care to argue
with your standards, I will follow your standards... No more and no less.

> (I understand that making it mandatory would have
> severely broken backward compatibility.)

I struggle to comprehend your tenses and moods, sorry. Coding standards
are rarely retroactive. If you want to fix the existing code to force
adherence to some kind of a standard, it's done in maintenance and a
certain protocol (with lots of reviews and testing) should be
established. And it's a topic for 'comp.software-eng' more than for
c.l.c++...

>
> That is:
>
> struct A {
> virtual void f();
> virtual void g();
> };
>
> struct B : A {
> void f() override; // remains legal with mandatory override
> void g(); // not legal with mandatory override
> };
>
> (I like override -- state your intentions, make code more
> readable, help catch errors -- but would have making it
> mandatory have been going to far?)

No.

> final:
>
> I understand that there is debate about whether using
> final ever makes sense, but leaving that aside:
>
> Would declaring a virtual function final in a base class
> ever make sense? I.e.,
>
> struct A {
> virtual void f() final;
> };
>
> The only thing I can think of would be to force A to
> be a "polymorphic" class, e.g., trigger RTTI, etc.,
> but this seems pretty contrived.

If the calling code is to be left unchanged, and the struct A is to be
left untouched, and A::f is not declared 'final', then I can circumvent
the call to that function by deriving from A and overriding 'f'. The
only way to ensure that 'f' is called by the caller (without changing
the calling code) is to declare 'f' final. It's a rare situation, but I
am sure it's encountered often enough to justify that feature to exist
in the language.

V
--
I do not respond to top-posted replies, please don't ask

Drew Lawson

unread,
Apr 22, 2015, 1:28:00 PM4/22/15
to
In article <mh8j2p$k50$1...@dont-email.me>
Victor Bazarov <v.ba...@comcast.invalid> writes:
>On 4/22/2015 12:15 PM, K. Frank wrote:
>> A couple of quick questions:
>>
>> override:
>>
>> If starting with a clean slate, would it have made
>> sense to make the use of override mandatory?
>
>"Would it *have made* sense"? Why subjunctive? Why not just "does it
>make sense"?

Probably because C++ is not "starting with a clean slate."
The language has been around for decades without "override."
But would it have made sense for the draft in 1983 to have required
it?

>Yes, it does make sense just as much as without it. I suppose you are
>referring to a convention of some kind, or a coding standard... Those
>are like religion. If I don't like your standards, I won't work for
>your group. If I care to work for your group more than I care to argue
>with your standards, I will follow your standards... No more and no less.
>
>> (I understand that making it mandatory would have
>> severely broken backward compatibility.)
>
>I struggle to comprehend your tenses and moods, sorry.

Then perhaps you shouldn't critique things you don't comprehend.

--
Drew Lawson | "But the senator, while insisting he was not
| intoxicated, could not explain his nudity."

Victor Bazarov

unread,
Apr 22, 2015, 2:07:24 PM4/22/15
to
I am sorry. I took it the OP was talking about setting up requirements
for a new project, not development of the language in the early 1980s.

K. Frank

unread,
Apr 22, 2015, 2:47:31 PM4/22/15
to
Hi Victor!

On Wednesday, April 22, 2015 at 12:44:19 PM UTC-4, Victor Bazarov wrote:
> On 4/22/2015 12:15 PM, K. Frank wrote:
> > A couple of quick questions:
> >
> > override:
> >
> > If starting with a clean slate, would it have made
> > sense to make the use of override mandatory?
>
> "Would it *have made* sense"? Why subjunctive? Why not just "does it
> make sense"?

Yes, sorry, I should have been more clear. Yes
(anticipating some of the comments downthread),
I was thinking about the language standard (not
about coding standards for a specific group or
project), hypothetically what one would have done
in the early 80's, hence the subjunctive.

> Yes, it does make sense just as much as without it. I suppose you are
> referring to a convention of some kind, or a coding standard...
> ...
> > (I like override -- state your intentions, make code more
> > readable, help catch errors -- but would have making it
> > mandatory have been going to far?)
>
> No.
>
> > final:
> >
> > I understand that there is debate about whether using
> > final ever makes sense, but leaving that aside:
> >
> > Would declaring a virtual function final in a base class
> > ever make sense? I.e.,
> >
> > struct A {
> > virtual void f() final;
> > };
> >
> > The only thing I can think of would be to force A to
> > be a "polymorphic" class, e.g., trigger RTTI, etc.,
> > but this seems pretty contrived.
>
> If the calling code is to be left unchanged, and the struct A is to be
> left untouched, and A::f is not declared 'final', then I can circumvent
> the call to that function by deriving from A and overriding 'f'.

To clarify: Just to complete that thought, if, furthermore,
I didn't declare the function virtual (and no final) so that
it couldn't be overridden, then the derived class could simply
hide A::f by declaring its own B::f, also circumventing forcing
A::f to be called.

Does this fit logically with your train of thought?

> The
> only way to ensure that 'f' is called by the caller (without changing
> the calling code) is to declare 'f' final. It's a rare situation, but I
> am sure it's encountered often enough to justify that feature to exist
> in the language.
>
> V


Thanks for your comments and perspective.


K. Frank

Richard

unread,
Apr 22, 2015, 2:48:59 PM4/22/15
to
[Please do not mail me a copy of your followup]

"K. Frank" <kfran...@gmail.com> spake the secret code
<6de96531-40e2-421c...@googlegroups.com> thusly:

>Would declaring a virtual function final in a base class
>ever make sense? I.e.,
>
>struct A {
> virtual void f() final;
>};

In languages that have "final", I have found that it makes unit
testing against those interfaces quite painful because most methods of
mocking interfaces use derive-and-override.

IMO, language features that make unit testing/mocking more difficult
are best avoided.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Victor Bazarov

unread,
Apr 22, 2015, 3:07:37 PM4/22/15
to
On 4/22/2015 2:47 PM, K. Frank wrote:
> Hi Victor!
> [..]
>>> final:
>>>
>>> I understand that there is debate about whether using
>>> final ever makes sense, but leaving that aside:
>>>
>>> Would declaring a virtual function final in a base class
>>> ever make sense? I.e.,
>>>
>>> struct A {
>>> virtual void f() final;
>>> };
>>>
>>> The only thing I can think of would be to force A to
>>> be a "polymorphic" class, e.g., trigger RTTI, etc.,
>>> but this seems pretty contrived.
>>
>> If the calling code is to be left unchanged, and the struct A is to be
>> left untouched, and A::f is not declared 'final', then I can circumvent
>> the call to that function by deriving from A and overriding 'f'.
>
> To clarify: Just to complete that thought, if, furthermore,
> I didn't declare the function virtual (and no final) so that
> it couldn't be overridden, then the derived class could simply
> hide A::f by declaring its own B::f, also circumventing forcing
> A::f to be called.
>
> Does this fit logically with your train of thought?

Well, if the function is not virtual, and the caller uses the inherited
type (not the derived one), the call is going to be statically resolved,
not polymorphically, so the problem of substituting does not really exist.

struct B { void foo(); };

void bar(B& b)
{
b.foo(); // calls B::foo
}

struct D : B { void foo(int); }; // hides B::foo

int main()
{
D d;
bar(d); // no problem here, no need of 'final'

Paavo Helde

unread,
Apr 22, 2015, 3:12:55 PM4/22/15
to
"K. Frank" <kfran...@gmail.com> wrote in news:6de96531-40e2-421c-9cb0-
f0f06b...@googlegroups.com:

> Hello Group!
>
> A couple of quick questions:
>
> override:
>
> If starting with a clean slate, would it have made
> sense to make the use of override mandatory?

Yes, I would vote for it, 'override' is quite helpful during refactoring.

>
> Would declaring a virtual function final in a base class
> ever make sense? I.e.,

Probably not, but this has never been a reason for banning something in C++
(not that you proposed that).

Öö Tiib

unread,
Apr 22, 2015, 3:44:39 PM4/22/15
to
On Wednesday, 22 April 2015 19:15:33 UTC+3, K. Frank wrote:
> Hello Group!
>
> A couple of quick questions:
>
> override:
>
> If starting with a clean slate, would it have made
> sense to make the use of override mandatory?
>
> (I understand that making it mandatory would have
> severely broken backward compatibility.)
>
> That is:
>
> struct A {
> virtual void f();
> virtual void g();
> };
>
> struct B : A {
> void f() override; // remains legal with mandatory override
> void g(); // not legal with mandatory override
> };
>
> (I like override -- state your intentions, make code more
> readable, help catch errors -- but would have making it
> mandatory have been going to far?)

It adds difficulties to those who have to compile same code with
decade old compiler and with new compiler. It usually means
preprocessor usage like that:

#include "A.hpp"

#if HAVE_OVERRIDE
#define OVERRIDE override
#else
#define OVERRIDE
#endif

struct B : A
{
void f() OVERRIDE;
void g() OVERRIDE;
};

It is not that pretty perspective. If you are lucky who can compile only
on new compiler then it is perhaps better to make a tool that adds
'override' automatically to the code.

> final:
>
> I understand that there is debate about whether using
> final ever makes sense, but leaving that aside:
>
> Would declaring a virtual function final in a base class
> ever make sense? I.e.,
>
> struct A {
> virtual void f() final;
> };
>
> The only thing I can think of would be to force A to
> be a "polymorphic" class, e.g., trigger RTTI, etc.,
> but this seems pretty contrived.

There may be some other scenarios but all are odd.

When I have reason to have final polymorphic hierarchy then I do not
expose it in interface. For example the hierarchy is hidden behind
pimpl and only envelope of it is defined in public headers. Then I
don't need to use 'final' and that sometimes simplifies unit testing.

David Brown

unread,
Apr 22, 2015, 6:27:21 PM4/22/15
to
Why not this:

#include "A.hpp"

#if HAVE_OVERRIDE
#else
#define override
#endif

struct B : A
{
void f() override;
void g() override;
};

Then it doesn't look too bad.

Ian Collins

unread,
Apr 22, 2015, 9:51:03 PM4/22/15
to
It's kinder on the eye, but may case problems if someone has used
override for a variable name! Don't forget that as a contextual
keyword, you can still use override as an identifier.

--
Ian Collins

David Brown

unread,
Apr 23, 2015, 3:17:28 AM4/23/15
to
The people writing parsers for C++ must /love/ these contextual keywords!

Yes, it would conflict with using override as an identifier. But I
think you'd get a fairly obvious error message if you did so, and change
the code appropriately when moving to C++11 (just because you /can/ use
"override" as an identifier as well as a contextual keyword, does not
make it a good idea).


Öö Tiib

unread,
Apr 23, 2015, 4:41:53 AM4/23/15
to
That ship has sailed long ago. Count of of little code snippets
to detect how close a parser is to give good impression of parsing
old C++ in a conforming manner is millions.
http://www.ace.nl/sites/default/files/SuperTest.RR_.pdf

> Yes, it would conflict with using override as an identifier. But I
> think you'd get a fairly obvious error message if you did so, and change
> the code appropriately when moving to C++11 (just because you /can/ use
> "override" as an identifier as well as a contextual keyword, does not
> make it a good idea).

It may be some important API that has contained such identifier for
decade. Authors have full right to complain that the members of
standard committee now try to get unfair advantage over their product
by breaking their API in new compiler. Hostility of authors (and
users) of it should not be taken lightly. ;)


Drew Lawson

unread,
Apr 23, 2015, 9:41:52 AM4/23/15
to
In article <mha67m$1h8$1...@dont-email.me>
David Brown <david...@hesbynett.no> writes:

>Yes, it would conflict with using override as an identifier. But I
>think you'd get a fairly obvious error message if you did so, and change
>the code appropriately when moving to C++11 (just because you /can/ use
>"override" as an identifier as well as a contextual keyword, does not
>make it a good idea).

Sure, it is a bad idea now. But it was reasonable in earlier versions.

It took at least a year of C++ before I stopped trying to use "new"
as a variable name. It was a very obvious and useful name for a
dynamically created item. I also had to break the habit of using
the pair "this" and "that."

I still occasionally run into head-slap mistakes like that, especially
when I have my head deep in the vocabulary of the problem domain
(class, public, float, switch -- lots of valid English words to
trip on), rather than the programming language.

--
Drew Lawson | And to those who lack the courage
| And say it's dangerous to try
| Well they just don't know
| That love eternal will not be denied
0 new messages