Topic: C++0x Wish list (override keyword)
Author: rmaddox@isicns.com (Randy Maddox)
Date: Fri, 12 Jul 2002 17:43:52 GMT Raw View
"Andrew N. Maximov" <maximov@obninsk.ru> wrote in message news:<1024834534.958893@basic.maxnet.ru>...
> What is really needed - is the override keyword.
IMHO, what is really needed is a way to catch the problem you describe
at compile time rather than having to debug to find it.
>
> If the override keyword placed before function declaration then this
> function really overrides. It is not new function and if it is not exists in
> the base class then compiler must give an error message. It helps to avoid
> frequency mistakes when functions parameters changed in the base class.
>
> struct A
> {
> virtual f(int id); <------- virtual f(string id); and what ?
> }
>
> struct B : A
> {
> f(int id); <--- f don't override ( and I can catch this only after
> debugging ... This is not very good. )
> }
>
Every C++ compiler I have worked with, including MSVC++, will generate
a warning when you inadvertantly hide a base class function. Just
turn up the warning level (You always compile with warnings set to a
high level anyway, right?) and the compiler will catch this for you.
No need to debug to find the problem.
The only issue with this solution is on MSVC++, where if you turn the
warning level up higher than 2 you get a bazillion warnings in every
MS header file you include. The solution is just to surround the
inclusion of all MS header files with a pragma to lower the warning
level for those include files. Example:
#pragma warning (push, 2) // push current warning level and set to
2
#include <windows.h> // no warnings at level 2
#pragma warning (pop) // restore previous warning level
Of course, you could just use gcc and set the warning level to the max
since none of its header files generate warnings at any level. Nice
clean headers. Too bad MS isn't the same way.
Randy.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@merlin.nerim.net>
Date: Tue, 9 Jul 2002 16:38:51 GMT Raw View
Alex Oren <response@myrealbox.com> writes:
| I would like a compiler to issue a warning if I'm hiding members of a
| base class.
The standard does not define what "warning" means.
What should be the "legal status/semantics" of a diagnostic for a
valid construct? That it is invalid? Or ...?
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 6 Jul 2002 06:18:58 GMT Raw View
In article <3D2386C9.6FEF2971@acm.org>, Pete Becker <petebecker@acm.org>
writes
>Alex Oren wrote:
>>
>> On Thu, 27 Jun 2002 20:25:09 GMT, Pete Becker wrote in
>> <3D1A5545.BF29C11C@acm.org>:
>>
>> > class Base
>> > {
>> > };
>> >
>> > class Derived : public Base
>> > {
>> > public:
>> > void f();
>> > };
>> >
>> > Now, in the course of maintenance, the company that supplied Base as
>> > part of a library adds a member function to it, so it now looks like
>> > this:
>> >
>> > class Base
>> > {
>> > public:
>> > void f();
>> > };
>> >
>> > If using the same name in a derived class is illegal (without some new
>> > keyword) you now have to rewrite your derived class, even though it
>> > would continue to work as it did before. Such a rule would make code
>> > much more fragile.
>>
>> I suggest a mandatory diagnostic.
>>
>
>I don't see what you're getting at. If using the name were illegal a
>diagnostic would be mandatory.
And if it were not then there are many who would howl (justifiably IMO)
if a diagnostic were required. The Standard is neither a tutorial nor a
substitute for education/training.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Alex Oren <response@myrealbox.com>
Date: Sat, 6 Jul 2002 06:20:26 GMT Raw View
On 3 Jul 2002 23:25:11 GMT, Pete Becker wrote in
<3D2386C9.6FEF2971@acm.org>:
> Alex Oren wrote:
> >
> > On Thu, 27 Jun 2002 20:25:09 GMT, Pete Becker wrote in
> > <3D1A5545.BF29C11C@acm.org>:
> >
> > > class Base
> > > {
> > > };
> > >
> > > class Derived : public Base
> > > {
> > > public:
> > > void f();
> > > };
> > >
> > > Now, in the course of maintenance, the company that supplied Base as
> > > part of a library adds a member function to it, so it now looks like
> > > this:
> > >
> > > class Base
> > > {
> > > public:
> > > void f();
> > > };
> > >
> > > If using the same name in a derived class is illegal (without some new
> > > keyword) you now have to rewrite your derived class, even though it
> > > would continue to work as it did before. Such a rule would make code
> > > much more fragile.
> >
> > I suggest a mandatory diagnostic.
> >
>
> I don't see what you're getting at. If using the name were illegal a
> diagnostic would be mandatory.
I would like a compiler to issue a warning if I'm hiding members of a
base class.
Best regards,
Alex.
--
To email me, replace "myrealbox" with "alexoren".
Sorry for the inconvenience. Blame the spammers.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Alex Oren <response@myrealbox.com>
Date: Wed, 3 Jul 2002 17:49:41 GMT Raw View
On Thu, 27 Jun 2002 20:25:09 GMT, Pete Becker wrote in
<3D1A5545.BF29C11C@acm.org>:
> class Base
> {
> };
>
> class Derived : public Base
> {
> public:
> void f();
> };
>
> Now, in the course of maintenance, the company that supplied Base as
> part of a library adds a member function to it, so it now looks like
> this:
>
> class Base
> {
> public:
> void f();
> };
>
> If using the same name in a derived class is illegal (without some new
> keyword) you now have to rewrite your derived class, even though it
> would continue to work as it did before. Such a rule would make code
> much more fragile.
I suggest a mandatory diagnostic.
Best regards,
Alex.
--
To email me, replace "myrealbox" with "alexoren".
Sorry for the inconvenience. Blame the spammers.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 3 Jul 2002 23:25:11 GMT Raw View
Alex Oren wrote:
>
> On Thu, 27 Jun 2002 20:25:09 GMT, Pete Becker wrote in
> <3D1A5545.BF29C11C@acm.org>:
>
> > class Base
> > {
> > };
> >
> > class Derived : public Base
> > {
> > public:
> > void f();
> > };
> >
> > Now, in the course of maintenance, the company that supplied Base as
> > part of a library adds a member function to it, so it now looks like
> > this:
> >
> > class Base
> > {
> > public:
> > void f();
> > };
> >
> > If using the same name in a derived class is illegal (without some new
> > keyword) you now have to rewrite your derived class, even though it
> > would continue to work as it did before. Such a rule would make code
> > much more fragile.
>
> I suggest a mandatory diagnostic.
>
I don't see what you're getting at. If using the name were illegal a
diagnostic would be mandatory.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "Hans Guijt" <hguijt@inter.nl.net>
Date: Thu, 27 Jun 2002 21:43:17 GMT Raw View
"John Nagle" <nagle@animats.com> schreef in bericht
news:3D19F9AC.7090302@animats.com...
> class try1 {
> public:
> virtual void foo(bool i)
> { printf("Try1: %d\n",int(i));}
> };
>
> class try2: public try1 {
> public:
> virtual void foo(float x)
> { printf("Try2: %f\n",x);}
> };
> ....
> try2 bar;
> bar.foo(true);
>
> Who gets called? Should the perfect match in try1,
> or the promotion in try2, be used? VC++ 6 picks
> try2, which seems questionable.
This is exactly why an override keyword is useful. If you had specified try2
like this:
class try2: public try1 {
public:
override void foo(float x)
{ printf("Try2: %f\n",x);}
};
...then it would not have compiled because the parameter lists don't match.
The override keyword provides a very cheap way to increase robustness
without interfering in any existing code, and as such is a welcome feature.
Of course the story is different if you intended try2::foo to be a different
function. In that case the lack of override does neither indicate a problem
nor correctness. This is unavoidable if backward compatibility is to be
maintained.
Hans Guijt
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: pdimov@mmltd.net (Peter Dimov)
Date: Fri, 28 Jun 2002 17:17:44 GMT Raw View
ros0230@iperbole.bologna.it (Natale Fietta) wrote in message news:<3d1b0bb2.269516@news.iperbole.bologna.it>...
>
> This is correct, try2::foo hide try1::foo, also if parameter lists are
> differents. (question to gurus: why the language was made this way ?
> why not to hide only function with the same signature ? it seem more
> natural)
Because name lookup works on names, and overload resolution does not
span scopes. The name 'foo' is found at try2, and the search stops
there.
Consider this example, where the difference between "overriding" and
"hiding", and between "function" and "name" is clearer:
struct X
{
int f;
};
struct Y: public X
{
typedef int f;
};
struct Z: public Y
{
int f();
};
Here Z::f hides Y::f, which in turn hides X::f. If it didn't, there
would be no way to use Z::f, or Y::f.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "Rob Staveley \(Tom\)" <rstaveley@seseit.com>
Date: Tue, 25 Jun 2002 21:37:05 GMT Raw View
"John Nagle" <nagle@animats.com> wrote in message
news:3D18AC9E.4080800@animats.com...
> I would go even further, and prohibit override of non-virtual
> functions. It's almost always an error, and leads to obscure bugs.
I disagree whole-heartedly. You get faster code avoiding virtual method
tables and you therefore don't want to make an overridable function virtual
if it doesn't need to be. A good example of this is an overridable function
called by a User Interface. Why make that virtual when you can be sure that
it isn't going to be called by the base class?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: pdimov@mmltd.net (Peter Dimov)
Date: Wed, 26 Jun 2002 15:50:54 GMT Raw View
John Nagle <nagle@animats.com> wrote in message news:<3D18AC9E.4080800@animats.com>...
> I would go even further, and prohibit override of non-virtual
> functions. It's almost always an error, and leads to obscure bugs.
You cannot override a non-virtual member function, or any other
member. You can only hide its name.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Wed, 26 Jun 2002 16:33:46 GMT Raw View
nagle@animats.com (John Nagle) wrote (abridged):
> I would go even further, and prohibit override of non-virtual
> functions.
But then a derived class has to know the names of all the private
functions of its base class, so as to avoid using the same names for its
own functions. Similarly, if we wanted to add a new private function to
the base class, we'd need to know the names of all the functions in all
derived classes so as to avoid breaking them.
Currently such name clashes with private, non-virtual functions are
harmless. I see no need to make them a compile-time error. It would make
"private" much less useful. In effect, a massive loss of encapsulation.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Wed, 26 Jun 2002 17:37:35 GMT Raw View
Dave Harris wrote:
> nagle@animats.com (John Nagle) wrote (abridged):
>
>> I would go even further, and prohibit override of non-virtual
>>functions.
>>
> But then a derived class has to know the names of all the private
> functions of its base class, so as to avoid using the same names for its
> own functions. Similarly, if we wanted to add a new private function to
> the base class, we'd need to know the names of all the functions in all
> derived classes so as to avoid breaking them.
>
> Currently such name clashes with private, non-virtual functions are
> harmless. I see no need to make them a compile-time error. It would make
> "private" much less useful. In effect, a massive loss of encapsulation.
Hmm. A key C++ design decision is that "private" prohibits
access, but does not hide. You don't get a "name not found"
error when trying to access a private function member from
outside the class; you get an error reporting that the name
is inaccessable. And "private" never changes which function
is picked when the same name appears at different places
in the class hierarchy.
If any name hiding is to be implied by "private", the
implications of overloading, templates, and "friend" need
to be thought through.
While we're on this subject, consider
class try1 {
public:
virtual void foo(bool i)
{ printf("Try1: %d\n",int(i));}
};
class try2: public try1 {
public:
virtual void foo(float x)
{ printf("Try2: %f\n",x);}
};
....
try2 bar;
bar.foo(true);
Who gets called? Should the perfect match in try1,
or the promotion in try2, be used? VC++ 6 picks
try2, which seems questionable.
John Nagle
Animats
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Wed, 26 Jun 2002 23:48:09 GMT Raw View
nagle@animats.com (John Nagle) wrote (abridged):
> If any name hiding is to be implied by "private", the
> implications of overloading, templates, and "friend" need
> to be thought through.
I agree. I don't suggest that private do name hiding. I am pointing out
that allowing derived classes to use the same names as their base classes
has some good consequences. C++ should continue to permit it, whatever the
accessibility of the names concerned.
> Who gets called? Should the perfect match in try1,
> or the promotion in try2, be used? VC++ 6 picks
> try2, which seems questionable.
VC++ 6 is right. The reasoning is explained quite well in the ARM.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Thu, 27 Jun 2002 15:56:57 GMT Raw View
On Wed, 26 Jun 2002 17:37:35 GMT, John Nagle <nagle@animats.com>
wrote:
> While we're on this subject, consider
>
>class try1 {
>public:
> virtual void foo(bool i)
> { printf("Try1: %d\n",int(i));}
>};
>
>class try2: public try1 {
>public:
> virtual void foo(float x)
> { printf("Try2: %f\n",x);}
>};
>....
> try2 bar;
> bar.foo(true);
>
>Who gets called? Should the perfect match in try1,
>or the promotion in try2, be used? VC++ 6 picks
>try2, which seems questionable.
This is correct, try2::foo hide try1::foo, also if parameter lists are
differents. (question to gurus: why the language was made this way ?
why not to hide only function with the same signature ? it seem more
natural)
If you want both foo accessible in try2 the easier solution i know is
using "using", this way:
>class try2: public try1 {
>public:
using try1::foo;
> virtual void foo(float x)
> { printf("Try2: %f\n",x);}
>};
Regards,
Natale Fietta
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: Thu, 27 Jun 2002 20:25:09 GMT Raw View
John Nagle wrote:
>
>Dave Harris wrote:
>
>> Currently such name clashes with private, non-virtual functions are
>> harmless. I see no need to make them a compile-time error. It would make
>> "private" much less useful. In effect, a massive loss of encapsulation.
>
> Hmm. A key C++ design decision is that "private" prohibits
> access, but does not hide. You don't get a "name not found"
> error when trying to access a private function member from
> outside the class; you get an error reporting that the name
> is inaccessable. And "private" never changes which function
> is picked when the same name appears at different places
> in the class hierarchy.
>
This misses the point.
class Base
{
};
class Derived : public Base
{
public:
void f();
};
Now, in the course of maintenance, the company that supplied Base as
part of a library adds a member function to it, so it now looks like
this:
class Base
{
public:
void f();
};
If using the same name in a derived class is illegal (without some new
keyword) you now have to rewrite your derived class, even though it
would continue to work as it did before. Such a rule would make code
much more fragile.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Alisdair Meredith <alisdair.sp-am.bl-ock.meredith@uk.renaultf1.com>
Date: Thu, 27 Jun 2002 20:26:45 GMT Raw View
I think the idea is that override also removes accidental name hiding.
If a member function is declared with the override directive it should
indicate [by my understanding of a non-standard thing!]
A member function of identical name and signiture is introduced in a
base class
That member is virtual
Likewise, any introduction of such a member function without the
override directive should throw up a warning diagnostic about the
accidental override, as many compiler do today for name hiding.
It should not check private methods of base classes, as clearly they are
inaccessible at this point.
The errors this new directive would most frequently catch are those
annoying mistypes where you swap the order of a couple of letter, such
as 'freind'. As member names grow this sort of error is increasingly
likely.
Similarly, when using a large 3rd party library with deep inheritance,
it is very easy to accidentally override a member function you were not
previously aware of.
Finally, it may make the language easier on beginners who may not be so
clear on the difference between virtual and non-functions and not clear
on when/how to use them. Diagnostics will let them know they have
likely made some mistake, even if it cannot correct their design.
You may gather I had positive results from a similar feature while
learning another language, so it has been tested in common practice.
[That alone does not justify a change to the language, but is typically
one of the prerequisites]
I also propose a final wrinkle that would be unique to a C++
implementation, as far as I am aware, to cover multiple inheritance.
The 'siamese twin' problem where two base classes include a member
function of the same name for different purposes [recounted in More
Exceptional C++, item 26] could be solved more simply if we were allowed
to use override to indicate which base class member function we were
overriding:
eg:
class A
{
protected:
virtual void Test( void );
};
class B
{
protected:
virtual void Test( void );
};
class C : public A, public B
{
protected:
override void A::Test( void ) { /* override usage in A*/ }
override void B::Test( void ) { /* override usage in B*/ }
};
AlisdairM
Peter Dimov wrote:
>
> John Nagle <nagle@animats.com> wrote in message news:<3D18AC9E.4080800@animats.com>...
> > I would go even further, and prohibit override of non-virtual
> > functions. It's almost always an error, and leads to obscure bugs.
>
> You cannot override a non-virtual member function, or any other
> member. You can only hide its name.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "Adam H. Peterson" <ahp6@email.byu.edu>
Date: Thu, 27 Jun 2002 21:26:28 GMT Raw View
> I would go even further, and prohibit override of non-virtual
> functions. It's almost always an error, and leads to obscure bugs.
>
> Yes, it will break some code, but I'd expect that most of the
> code it breaks was broken anyway.
I strongly disagree. It would force me to come up with new creative names
when the same name (and noting that the function is marked neither as
"virtual" nor "override") would be clearer.
Furthermore, it would break some of my template usage. E.g.:
class Base {
public:
void doJob() const;
};
class Derived : public Base {
public:
void doJob() const;
};
template<class IsABase>
class BaseWrapper : IsA<IsABase,Base> {
public:
void templateDoJob() const { iab.doJob(); }
private:
IsABase iab;
};
In the above sample, I don't need to use dynamic polymorphism at all. Which
doJob() is called is resolved statically, and (IMO) fairly clear. Yet the
above suggestion would make the code illegal. It would also force me to use
polymorphism that is never used; a simple change of names would irreparably
break the template.
A side question: how would the proposal affect operator functions? The
derived function would have the same name, and in some cases even the same
signature. Would this force these functions to be polymorphic?
Nevertheless, I am otherwise in favor of the override keyword as Andrew
originally suggested. I have had to track down bugs resulting from subtlely
mismatched function signatures preventing proper polymorphism, and a
compiler diagnostic would have saved me hours.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: "Andrew N. Maximov" <maximov@obninsk.ru>
Date: Mon, 24 Jun 2002 01:06:05 GMT Raw View
What is really needed - is the override keyword.
If the override keyword placed before function declaration then this
function really overrides. It is not new function and if it is not exists in
the base class then compiler must give an error message. It helps to avoid
frequency mistakes when functions parameters changed in the base class.
struct A
{
virtual f(int id); <------- virtual f(string id); and what ?
}
struct B : A
{
f(int id); <--- f don't override ( and I can catch this only after
debugging ... This is not very good. )
}
If you say: "Use pure virtual functions" - this is not what I need. Often
virtual function in base class must have default realization.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Alisdair Meredith <alisdair.sp-am.bl-ock.meredith@uk.renaultf1.com>
Date: Mon, 24 Jun 2002 08:53:21 GMT Raw View
I would go further, and suggest that overriding virtual functions
without using this 'override' keyword should also issue a diagnostic
[which could be turned off with compiler switches, for all the existing
code out there] to catch cases of 'accidental' overrides. This is most
typically a problem when using 3rd party libraries frameworks with a
deep inheritence hierarchy.
It would be easy enough to #define override so that it has no effect on
existing compilers as well. After all, this only produces diagnostics
[which may be 'errors' depending on compiler switches/implementation] so
defining it to do nothing has no effect on code, you simply lose the
extra diagnostic information.
In this way, it could be added to existing code with minimal impact
while providing useful diagnostics into the future.
Note that pure virtual functions address an entirely different problem,
that the funtion MUST be overridden. override indicates the explicit
intention that the function IS overriding, and must be present/virtual
in the base class.
The one place my further extension breaks is with existing code that
tags 'virtual' on each override as well. In my new scheme, this should
be 'override' and using virtual here should issue a diagnostic. As that
is a change to existing behaviour, I am quite sure it will not be so
popular! As I don't have a mountain of legacy code to support (yet) I
am quite happy to argue for better diagnostics with a 'minimal' impact
on existing code, and understand this will not be the majority view.
AlisdairM
"Andrew N. Maximov" wrote:
>
> What is really needed - is the override keyword.
>
> If the override keyword placed before function declaration then this
> function really overrides. It is not new function and if it is not exists in
> the base class then compiler must give an error message. It helps to avoid
> frequency mistakes when functions parameters changed in the base class.
>
> struct A
> {
> virtual f(int id); <------- virtual f(string id); and what ?
> }
>
> struct B : A
> {
> f(int id); <--- f don't override ( and I can catch this only after
> debugging ... This is not very good. )
> }
>
> If you say: "Use pure virtual functions" - this is not what I need. Often
> virtual function in base class must have default realization.
>
> ---
> [ 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.jamesd.demon.co.uk/csc/faq.html ]
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Bernd Strieder <strieder@student.uni-kl.de>
Date: Mon, 24 Jun 2002 17:17:05 GMT Raw View
Andrew N. Maximov wrote:
> What is really needed - is the override keyword.
IMO, no, it is not needed. It would support bad programming habits.
>
> If the override keyword placed before function declaration then this
> function really overrides. It is not new function and if it is not exists
> in the base class then compiler must give an error message. It helps to
> avoid frequency mistakes when functions parameters changed in the base
> class.
Creating class hierarchies with instable base classes, deliberately
overriding here and there, produces code that is hard to understand, and
therefore hard to (re)use.
Having "override" cluttered all over the code, it would become tedious to
remove a base class, one of its inheritants taking over its role. I'm sure
there are more situations, where "override" ends in tedious work.
>
> struct A
> {
> virtual f(int id); <------- virtual f(string id); and what ?
> }
>
> struct B : A
> {
> f(int id); <--- f don't override ( and I can catch this only after
> debugging ... This is not very good. )
> }
Do you want better support of try-and-error programming style? If yes, then
override is the peak of the iceberg.
>
> If you say: "Use pure virtual functions" - this is not what I need. Often
> virtual function in base class must have default realization.
Just using virtual functions doesn't make it better. Change the design,
avoid getting into the cluttered overriding business from the beginning.
Using an as flat as possible inheritance tree with mainly pure virtual
functions in the base class avoids many of the problems with overriding.
Use the template pattern, make the virtual functions non-public, and let
your clients call classes of your hierarchy only through some non-virtual
functions in the base class. All of this together will isolate the maybe
complicated relations of the virtual functions from the client, and it
becomes possible to implement stable handling of overridden variants of
some functions. The idea is to separate the different reasons to override
from each other. This will also help you a lot in dealing with the
interfaces in question.
struct A {
// public interface, designed to not be overridden by inheritants
void f(int z) {do_f(static_cast<float>(z));}
void f(char c) {do_f(static_cast<float>(c));}
// enlarging the public interface doesn't involve inheritants
...
protected:
virtual void do_f (float) = 0;
virtual void do_f (double) = 0;
}
Objectively, I'm just against "override". But, there are many existing
inheritance trees in the real world combining the worst design
anti-pattern. If there were enough people wanting some help handling them,
and enough of the creators of those trees were willing to add that override
wherever needed into old code, producing another bugfix release, then
override would serve its purpose. Using it in new code should be avoided.
The newly introduced keyword would be deprecated by design, but no reason
to leave it alone.
Bernd Strieder
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Tue, 25 Jun 2002 17:51:50 GMT Raw View
I would go even further, and prohibit override of non-virtual
functions. It's almost always an error, and leads to obscure bugs.
Yes, it will break some code, but I'd expect that most of the
code it breaks was broken anyway.
John Nagle
Alisdair Meredith wrote:
> I would go further...
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]