Re: Final keyword in C++
"Alf P. Steinbach" wrote:
* kanze:
SuperKoko wrote:
[...]
Anyway, I fear that, if 'final' is added to the language,
programmers will abuse of this new keyword (uselessly
reducing extensibility), as they did in Java.
Interesting. From what I've seen of Java, just the opposite
is the case; most programmers don't bother to declare a
function final, even if they're not prepared to handle a
different implementation of it.
Unless you intentionally design a function to be replaced,
it generally cannot be robustly replaced. Almost none of
the Java programmers I've known, and very little of the code
I've seen, actually considers the issue. Which means that
you cannot override most functions and still be sure that
the code works, but the functions are not declared final.
I think the issue is much more complex than that.
I agree that the issue can be very complex, and that knowing
when final is appropriate requires a thorough understanding of
the design issues involved.
E.g., consider adding tracing of member function calls for
some pre-existing frozen class. I think the complexity is so
high that in a discussion of pro and con every argument from
one side could be countered by an argument from the other
side, and vice versa, ad nauseam and infinitum, and thus, I
think that disqualifies the notion of 'final' for member
functions: when it's that unclear, adding complexity to the
language is IMO ungood.
When working in Java, I had more than a few cases where we used
it, to good avail. The typical example is where you implement
an abstract base class (an interface in Java), and the
implementation itself uses the template pattern. If the user
overrides any of your functions, you'll be in deep trouble,
since they define the pre- and post-conditions, and ensure the
invariants.
It's interesting to note that my opinion here is based on
concrete experience. I'm not advocating final for classes,
because it has been my experience that programmers (even very
average programmers) don't generally derive from a class that
wasn't designed for derivation. It's simply not a problem. (In
C++. Java needs it for other reasons.) On the other hand, I've
really had problems with programmers overriding the wrong
functions when they derived from a class meant to act as a base
class. We only added final when we started having problems.
This may be related to the organizational structure I was
working in: we had technical experts, like myself, writing the
basic framework, and domain experts (specialists in banking)
writing the layers on top. The domain experts weren't any
better with the technical issues than I was with the domain
issues, and one of the principal goals was precisely to limit
the problems they could encounter---thus, for example, although
the application was multi-threaded, the domain experts never had
to deal with threading issues.
I think that such an organization is not that infrequent; at
least I tend to find myself in one often. And obviously, domain
experts are still expected to read the documentation; if the
documentation of my class says not to override this function, we
expect them not to do so. But nobody's perfect, of course, and
a compiler error when the domain expert compiles is definitly
preferrable to a week long debugging session because your class
invariants don't hold (which causes problems far from the site
of the actual error). Admittedly, most of the time, a five
minute code review is sufficient to find the error, and week
long debugging sessions, while not unheard of, aren't all that
frequent either. So I'm not adament about the issue; the gain
is relatively small. On the other hand, so is the cost (in
terms of added complexity), so why not.
At any rate, the question is moot. There's currently no
proposal before the committe (at least that I know of), I don't
feel motivated enough to write one, even though I'd definitly
endorse one if someone else did the work, and it's really too
late for new proposals anyway. So it's not going to happen.
As the OP noted there is already an idiom for 'final' for C++
classes (it's in the FAQ). And the OP's argument is that
language support could allow optimizations. Well, I think it
would be an optimization very seldom "activated" for
well-designed code, and in my humble opinion C++ has enough
cases of making premature optimization all too easy.
So I think 'final' for classes is ungood too.
For classes, I agree. I'm not familiar with the idioms which
require derivation, but people who I trust, and who know more
about meta-programming that I do, say they exist. And about the
only motivation for banning derivation that I can think of is to
forbid overriding functions that you don't want to have
overridden, and that's best handled on a function by function
basis anyway. (Again, Java is different. The somewhat strange
interactions between package and protected access mean that
there are cases where you want to forbid derivation for security
reasons. Cases which occur more frequently than they would in
C++ because of the lack of friends---if another class needs
access to your internal data, the only way to grant it is to
make both classes members of the same package, and grant package
access. Which also grants protected access.)
--
James Kanze GABI Software
Conseils en informatique orient9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S9mard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]